Merge pull request #101139 from roberth/lib-use-static-scope-checking
lib: Use Nix's static scope checking, fix error message, optimize
This commit is contained in:
commit
7102388834
9 changed files with 265 additions and 86 deletions
|
@ -14,9 +14,25 @@
|
||||||
*/
|
*/
|
||||||
{ lib }:
|
{ lib }:
|
||||||
let
|
let
|
||||||
inherit (builtins) trace isAttrs isList isInt
|
inherit (lib)
|
||||||
head substring attrNames;
|
isInt
|
||||||
inherit (lib) id elem isFunction;
|
attrNames
|
||||||
|
isList
|
||||||
|
isAttrs
|
||||||
|
substring
|
||||||
|
addErrorContext
|
||||||
|
attrValues
|
||||||
|
concatLists
|
||||||
|
concatStringsSep
|
||||||
|
const
|
||||||
|
elem
|
||||||
|
generators
|
||||||
|
head
|
||||||
|
id
|
||||||
|
isDerivation
|
||||||
|
isFunction
|
||||||
|
mapAttrs
|
||||||
|
trace;
|
||||||
in
|
in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
@ -94,7 +110,7 @@ rec {
|
||||||
trace: { a = { b = {…}; }; }
|
trace: { a = { b = {…}; }; }
|
||||||
=> null
|
=> null
|
||||||
*/
|
*/
|
||||||
traceSeqN = depth: x: y: with lib;
|
traceSeqN = depth: x: y:
|
||||||
let snip = v: if isList v then noQuotes "[…]" v
|
let snip = v: if isList v then noQuotes "[…]" v
|
||||||
else if isAttrs v then noQuotes "{…}" v
|
else if isAttrs v then noQuotes "{…}" v
|
||||||
else v;
|
else v;
|
||||||
|
@ -149,7 +165,7 @@ rec {
|
||||||
*/
|
*/
|
||||||
runTests =
|
runTests =
|
||||||
# Tests to run
|
# 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 [];
|
let testsToRun = if tests ? tests then tests.tests else [];
|
||||||
in if (substring 0 4 name == "test" || elem name testsToRun)
|
in if (substring 0 4 name == "test" || elem name testsToRun)
|
||||||
&& ((testsToRun == []) || elem name tests.tests)
|
&& ((testsToRun == []) || elem name tests.tests)
|
||||||
|
@ -176,9 +192,9 @@ rec {
|
||||||
+ "and will be removed in the next release. "
|
+ "and will be removed in the next release. "
|
||||||
+ "Please use more specific concatenation "
|
+ "Please use more specific concatenation "
|
||||||
+ "for your uses (`lib.concat(Map)StringsSep`)." )
|
+ "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 "
|
trace ( "Warning: `showVal` is deprecated "
|
||||||
+ "and will be removed in the next release, "
|
+ "and will be removed in the next release, "
|
||||||
+ "please use `traceSeqN`" )
|
+ "please use `traceSeqN`" )
|
||||||
|
@ -226,7 +242,7 @@ rec {
|
||||||
trace ( "Warning: `addErrorContextToAttrs` is deprecated "
|
trace ( "Warning: `addErrorContextToAttrs` is deprecated "
|
||||||
+ "and will be removed in the next release. "
|
+ "and will be removed in the next release. "
|
||||||
+ "Please use `builtins.addErrorContext` directly." )
|
+ "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
|
# example: (traceCallXml "myfun" id 3) will output something like
|
||||||
# calling myfun arg 1: 3 result: 3
|
# calling myfun arg 1: 3 result: 3
|
||||||
|
|
|
@ -9,7 +9,7 @@ let
|
||||||
|
|
||||||
lib = makeExtensible (self: let
|
lib = makeExtensible (self: let
|
||||||
callLibs = file: import file { lib = self; };
|
callLibs = file: import file { lib = self; };
|
||||||
in with self; {
|
in {
|
||||||
|
|
||||||
# often used, or depending on very little
|
# often used, or depending on very little
|
||||||
trivial = callLibs ./trivial.nix;
|
trivial = callLibs ./trivial.nix;
|
||||||
|
@ -54,7 +54,7 @@ let
|
||||||
filesystem = callLibs ./filesystem.nix;
|
filesystem = callLibs ./filesystem.nix;
|
||||||
|
|
||||||
# back-compat aliases
|
# back-compat aliases
|
||||||
platforms = systems.doubles;
|
platforms = self.systems.doubles;
|
||||||
|
|
||||||
# linux kernel configuration
|
# linux kernel configuration
|
||||||
kernel = callLibs ./kernel.nix;
|
kernel = callLibs ./kernel.nix;
|
||||||
|
@ -63,14 +63,14 @@ let
|
||||||
deepSeq elem elemAt filter genericClosure genList getAttr
|
deepSeq elem elemAt filter genericClosure genList getAttr
|
||||||
hasAttr head isAttrs isBool isInt isList isString length
|
hasAttr head isAttrs isBool isInt isList isString length
|
||||||
lessThan listToAttrs pathExists readFile replaceStrings seq
|
lessThan listToAttrs pathExists readFile replaceStrings seq
|
||||||
stringLength sub substring tail;
|
stringLength sub substring tail trace;
|
||||||
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
|
bitNot boolToString mergeAttrs flip mapNullable inNixShell isFloat min max
|
||||||
importJSON importTOML warn info showWarnings nixpkgsVersion version mod compare
|
importJSON importTOML warn info showWarnings nixpkgsVersion version mod compare
|
||||||
splitByAndCompare functionArgs setFunctionArgs isFunction toHexString toBaseDigits;
|
splitByAndCompare functionArgs setFunctionArgs isFunction toHexString toBaseDigits;
|
||||||
inherit (fixedPoints) fix fix' converge extends composeExtensions
|
inherit (self.fixedPoints) fix fix' converge extends composeExtensions
|
||||||
makeExtensible makeExtensibleWithCustomName;
|
makeExtensible makeExtensibleWithCustomName;
|
||||||
inherit (attrsets) attrByPath hasAttrByPath setAttrByPath
|
inherit (self.attrsets) attrByPath hasAttrByPath setAttrByPath
|
||||||
getAttrFromPath attrVals attrValues getAttrs catAttrs filterAttrs
|
getAttrFromPath attrVals attrValues getAttrs catAttrs filterAttrs
|
||||||
filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs
|
filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs
|
||||||
mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
|
mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
|
||||||
|
@ -79,13 +79,13 @@ let
|
||||||
recursiveUpdate matchAttrs overrideExisting getOutput getBin
|
recursiveUpdate matchAttrs overrideExisting getOutput getBin
|
||||||
getLib getDev getMan chooseDevOutputs zipWithNames zip
|
getLib getDev getMan chooseDevOutputs zipWithNames zip
|
||||||
recurseIntoAttrs dontRecurseIntoAttrs;
|
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
|
concatMap flatten remove findSingle findFirst any all count
|
||||||
optional optionals toList range partition zipListsWith zipLists
|
optional optionals toList range partition zipListsWith zipLists
|
||||||
reverseList listDfs toposort sort naturalSort compareLists take
|
reverseList listDfs toposort sort naturalSort compareLists take
|
||||||
drop sublist last init crossLists unique intersectLists
|
drop sublist last init crossLists unique intersectLists
|
||||||
subtractLists mutuallyExclusive groupBy groupBy';
|
subtractLists mutuallyExclusive groupBy groupBy';
|
||||||
inherit (strings) concatStrings concatMapStrings concatImapStrings
|
inherit (self.strings) concatStrings concatMapStrings concatImapStrings
|
||||||
intersperse concatStringsSep concatMapStringsSep
|
intersperse concatStringsSep concatMapStringsSep
|
||||||
concatImapStringsSep makeSearchPath makeSearchPathOutput
|
concatImapStringsSep makeSearchPath makeSearchPathOutput
|
||||||
makeLibraryPath makeBinPath optionalString
|
makeLibraryPath makeBinPath optionalString
|
||||||
|
@ -97,19 +97,19 @@ let
|
||||||
nameFromURL enableFeature enableFeatureAs withFeature
|
nameFromURL enableFeature enableFeatureAs withFeature
|
||||||
withFeatureAs fixedWidthString fixedWidthNumber isStorePath
|
withFeatureAs fixedWidthString fixedWidthNumber isStorePath
|
||||||
toInt readPathsFromFile fileContents;
|
toInt readPathsFromFile fileContents;
|
||||||
inherit (stringsWithDeps) textClosureList textClosureMap
|
inherit (self.stringsWithDeps) textClosureList textClosureMap
|
||||||
noDepEntry fullDepEntry packEntry stringAfter;
|
noDepEntry fullDepEntry packEntry stringAfter;
|
||||||
inherit (customisation) overrideDerivation makeOverridable
|
inherit (self.customisation) overrideDerivation makeOverridable
|
||||||
callPackageWith callPackagesWith extendDerivation hydraJob
|
callPackageWith callPackagesWith extendDerivation hydraJob
|
||||||
makeScope;
|
makeScope;
|
||||||
inherit (meta) addMetaAttrs dontDistribute setName updateName
|
inherit (self.meta) addMetaAttrs dontDistribute setName updateName
|
||||||
appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio
|
appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio
|
||||||
hiPrioSet;
|
hiPrioSet;
|
||||||
inherit (sources) pathType pathIsDirectory cleanSourceFilter
|
inherit (self.sources) pathType pathIsDirectory cleanSourceFilter
|
||||||
cleanSource sourceByRegex sourceFilesBySuffices
|
cleanSource sourceByRegex sourceFilesBySuffices
|
||||||
commitIdFromGitRepo cleanSourceWith pathHasContext
|
commitIdFromGitRepo cleanSourceWith pathHasContext
|
||||||
canCleanSource pathIsRegularFile pathIsGitRepo;
|
canCleanSource pathIsRegularFile pathIsGitRepo;
|
||||||
inherit (modules) evalModules unifyModuleSyntax
|
inherit (self.modules) evalModules unifyModuleSyntax
|
||||||
applyIfFunction mergeModules
|
applyIfFunction mergeModules
|
||||||
mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
|
mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
|
||||||
pushDownProperties dischargeProperties filterOverrides
|
pushDownProperties dischargeProperties filterOverrides
|
||||||
|
@ -119,21 +119,21 @@ let
|
||||||
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
|
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
|
||||||
mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
|
mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
|
||||||
mkAliasOptionModule doRename;
|
mkAliasOptionModule doRename;
|
||||||
inherit (options) isOption mkEnableOption mkSinkUndeclaredOptions
|
inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions
|
||||||
mergeDefaultOption mergeOneOption mergeEqualOption getValues
|
mergeDefaultOption mergeOneOption mergeEqualOption getValues
|
||||||
getFiles optionAttrSetToDocList optionAttrSetToDocList'
|
getFiles optionAttrSetToDocList optionAttrSetToDocList'
|
||||||
scrubOptionValue literalExample showOption showFiles
|
scrubOptionValue literalExample showOption showFiles
|
||||||
unknownModule mkOption;
|
unknownModule mkOption;
|
||||||
inherit (types) isType setType defaultTypeMerge defaultFunctor
|
inherit (self.types) isType setType defaultTypeMerge defaultFunctor
|
||||||
isOptionType mkOptionType;
|
isOptionType mkOptionType;
|
||||||
inherit (asserts)
|
inherit (self.asserts)
|
||||||
assertMsg assertOneOf;
|
assertMsg assertOneOf;
|
||||||
inherit (debug) addErrorContextToAttrs traceIf traceVal traceValFn
|
inherit (self.debug) addErrorContextToAttrs traceIf traceVal traceValFn
|
||||||
traceXMLVal traceXMLValMarked traceSeq traceSeqN traceValSeq
|
traceXMLVal traceXMLValMarked traceSeq traceSeqN traceValSeq
|
||||||
traceValSeqFn traceValSeqN traceValSeqNFn traceShowVal
|
traceValSeqFn traceValSeqN traceValSeqNFn traceShowVal
|
||||||
traceShowValMarked showVal traceCall traceCall2 traceCall3
|
traceShowValMarked showVal traceCall traceCall2 traceCall3
|
||||||
traceValIfNot runTests testAllTrue traceCallXml attrNamesToStr;
|
traceValIfNot runTests testAllTrue traceCallXml attrNamesToStr;
|
||||||
inherit (misc) maybeEnv defaultMergeArg defaultMerge foldArgs
|
inherit (self.misc) maybeEnv defaultMergeArg defaultMerge foldArgs
|
||||||
maybeAttrNullable maybeAttr ifEnable checkFlag getValue
|
maybeAttrNullable maybeAttr ifEnable checkFlag getValue
|
||||||
checkReqs uniqList uniqListExt condConcat lazyGenericClosure
|
checkReqs uniqList uniqListExt condConcat lazyGenericClosure
|
||||||
innerModifySumArgs modifySumArgs innerClosePropagation
|
innerModifySumArgs modifySumArgs innerClosePropagation
|
||||||
|
@ -143,7 +143,7 @@ let
|
||||||
mergeAttrsByFuncDefaultsClean mergeAttrBy
|
mergeAttrsByFuncDefaultsClean mergeAttrBy
|
||||||
fakeHash fakeSha256 fakeSha512
|
fakeHash fakeSha256 fakeSha512
|
||||||
nixType imap;
|
nixType imap;
|
||||||
inherit (versions)
|
inherit (self.versions)
|
||||||
splitVersion;
|
splitVersion;
|
||||||
});
|
});
|
||||||
in lib
|
in lib
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
# General list operations.
|
# General list operations.
|
||||||
|
|
||||||
{ lib }:
|
{ lib }:
|
||||||
with lib.trivial;
|
|
||||||
let
|
let
|
||||||
inherit (lib.strings) toInt;
|
inherit (lib.strings) toInt;
|
||||||
|
inherit (lib.trivial) compare min;
|
||||||
in
|
in
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,53 @@
|
||||||
{ lib }:
|
{ lib }:
|
||||||
|
|
||||||
with lib.lists;
|
let
|
||||||
with lib.strings;
|
inherit (lib)
|
||||||
with lib.trivial;
|
all
|
||||||
with lib.attrsets;
|
any
|
||||||
with lib.options;
|
attrByPath
|
||||||
with lib.debug;
|
attrNames
|
||||||
with lib.types;
|
catAttrs
|
||||||
|
concatLists
|
||||||
|
concatMap
|
||||||
|
count
|
||||||
|
elem
|
||||||
|
filter
|
||||||
|
findFirst
|
||||||
|
flip
|
||||||
|
foldl
|
||||||
|
foldl'
|
||||||
|
getAttrFromPath
|
||||||
|
head
|
||||||
|
id
|
||||||
|
imap1
|
||||||
|
isAttrs
|
||||||
|
isBool
|
||||||
|
isFunction
|
||||||
|
isString
|
||||||
|
length
|
||||||
|
mapAttrs
|
||||||
|
mapAttrsToList
|
||||||
|
mapAttrsRecursiveCond
|
||||||
|
min
|
||||||
|
optional
|
||||||
|
optionalAttrs
|
||||||
|
optionalString
|
||||||
|
recursiveUpdate
|
||||||
|
reverseList sort
|
||||||
|
setAttrByPath
|
||||||
|
toList
|
||||||
|
types
|
||||||
|
warn
|
||||||
|
;
|
||||||
|
inherit (lib.options)
|
||||||
|
isOption
|
||||||
|
mkOption
|
||||||
|
showDefs
|
||||||
|
showFiles
|
||||||
|
showOption
|
||||||
|
unknownModule
|
||||||
|
;
|
||||||
|
in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
|
@ -616,7 +657,7 @@ rec {
|
||||||
fixupOptionType = loc: opt:
|
fixupOptionType = loc: opt:
|
||||||
let
|
let
|
||||||
options = opt.options or
|
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:
|
f = tp:
|
||||||
let optionSetIn = type: (tp.name == type) && (tp.functor.wrapped.name == "optionSet");
|
let optionSetIn = type: (tp.name == type) && (tp.functor.wrapped.name == "optionSet");
|
||||||
in
|
in
|
||||||
|
|
|
@ -1,11 +1,40 @@
|
||||||
# Nixpkgs/NixOS option handling.
|
# Nixpkgs/NixOS option handling.
|
||||||
{ lib }:
|
{ lib }:
|
||||||
|
|
||||||
with lib.trivial;
|
let
|
||||||
with lib.lists;
|
inherit (lib)
|
||||||
with lib.attrsets;
|
all
|
||||||
with lib.strings;
|
collect
|
||||||
|
concatLists
|
||||||
|
concatMap
|
||||||
|
elemAt
|
||||||
|
filter
|
||||||
|
foldl'
|
||||||
|
head
|
||||||
|
isAttrs
|
||||||
|
isBool
|
||||||
|
isDerivation
|
||||||
|
isFunction
|
||||||
|
isInt
|
||||||
|
isList
|
||||||
|
isString
|
||||||
|
length
|
||||||
|
mapAttrs
|
||||||
|
optional
|
||||||
|
optionals
|
||||||
|
take
|
||||||
|
;
|
||||||
|
inherit (lib.attrsets)
|
||||||
|
optionalAttrs
|
||||||
|
;
|
||||||
|
inherit (lib.strings)
|
||||||
|
concatMapStrings
|
||||||
|
concatStringsSep
|
||||||
|
;
|
||||||
|
inherit (lib.types)
|
||||||
|
mkOptionType
|
||||||
|
;
|
||||||
|
in
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
/* Returns true when the given argument is an option
|
/* Returns true when the given argument is an option
|
||||||
|
@ -110,7 +139,7 @@ rec {
|
||||||
# Return early if we only have one element
|
# Return early if we only have one element
|
||||||
# This also makes it work for functions, because the foldl' below would try
|
# This also makes it work for functions, because the foldl' below would try
|
||||||
# to compare the first element with itself, which is false for functions
|
# to compare the first element with itself, which is false for functions
|
||||||
else if length defs == 1 then (elemAt defs 0).value
|
else if length defs == 1 then (head defs).value
|
||||||
else (foldl' (first: def:
|
else (foldl' (first: def:
|
||||||
if def.value != first.value then
|
if def.value != first.value then
|
||||||
throw "The option `${showOption loc}' has conflicting definition values:${showDefs [ first def ]}"
|
throw "The option `${showOption loc}' has conflicting definition values:${showDefs [ first def ]}"
|
||||||
|
|
|
@ -1,16 +1,33 @@
|
||||||
# Functions for copying sources to the Nix store.
|
# Functions for copying sources to the Nix store.
|
||||||
{ lib }:
|
{ lib }:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (builtins)
|
||||||
|
hasContext
|
||||||
|
match
|
||||||
|
readDir
|
||||||
|
storeDir
|
||||||
|
tryEval
|
||||||
|
;
|
||||||
|
inherit (lib)
|
||||||
|
filter
|
||||||
|
getAttr
|
||||||
|
isString
|
||||||
|
pathExists
|
||||||
|
readFile
|
||||||
|
split
|
||||||
|
;
|
||||||
|
in
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
# Returns the type of a path: regular (for file), symlink, or directory
|
# 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
|
# 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
|
# 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
|
# Bring in a path as a source, filtering out all Subversion and CVS
|
||||||
# directories, as well as backup files (*~).
|
# directories, as well as backup files (*~).
|
||||||
|
@ -19,8 +36,8 @@ rec {
|
||||||
(baseName == ".git" || type == "directory" && (baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
|
(baseName == ".git" || type == "directory" && (baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
|
||||||
# Filter out editor backup / swap files.
|
# Filter out editor backup / swap files.
|
||||||
lib.hasSuffix "~" baseName ||
|
lib.hasSuffix "~" baseName ||
|
||||||
builtins.match "^\\.sw[a-z]$" baseName != null ||
|
match "^\\.sw[a-z]$" baseName != null ||
|
||||||
builtins.match "^\\..*\\.sw[a-z]$" baseName != null ||
|
match "^\\..*\\.sw[a-z]$" baseName != null ||
|
||||||
|
|
||||||
# Filter out generates files.
|
# Filter out generates files.
|
||||||
lib.hasSuffix ".o" baseName ||
|
lib.hasSuffix ".o" baseName ||
|
||||||
|
@ -89,7 +106,7 @@ rec {
|
||||||
in lib.cleanSourceWith {
|
in lib.cleanSourceWith {
|
||||||
filter = (path: type:
|
filter = (path: type:
|
||||||
let relPath = lib.removePrefix (toString origSrc + "/") (toString path);
|
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;
|
inherit src;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -102,13 +119,12 @@ rec {
|
||||||
in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
|
in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
|
||||||
in cleanSourceWith { inherit filter; src = path; };
|
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
|
# Get the commit id of a git repo
|
||||||
# Example: commitIdFromGitRepo <nixpkgs/.git>
|
# Example: commitIdFromGitRepo <nixpkgs/.git>
|
||||||
commitIdFromGitRepo =
|
commitIdFromGitRepo =
|
||||||
let readCommitFromFile = file: path:
|
let readCommitFromFile = file: path:
|
||||||
with builtins;
|
|
||||||
let fileName = toString path + "/" + file;
|
let fileName = toString path + "/" + file;
|
||||||
packedRefsName = toString path + "/packed-refs";
|
packedRefsName = toString path + "/packed-refs";
|
||||||
absolutePath = base: path:
|
absolutePath = base: path:
|
||||||
|
@ -145,11 +161,11 @@ rec {
|
||||||
# packed-refs file, so we have to grep through it:
|
# packed-refs file, so we have to grep through it:
|
||||||
then
|
then
|
||||||
let fileContent = readFile packedRefsName;
|
let fileContent = readFile packedRefsName;
|
||||||
matchRef = builtins.match "([a-z0-9]+) ${file}";
|
matchRef = match "([a-z0-9]+) ${file}";
|
||||||
isRef = s: builtins.isString s && (matchRef s) != null;
|
isRef = s: isString s && (matchRef s) != null;
|
||||||
# there is a bug in libstdc++ leading to stackoverflow for long strings:
|
# there is a bug in libstdc++ leading to stackoverflow for long strings:
|
||||||
# https://github.com/NixOS/nix/issues/2147#issuecomment-659868795
|
# 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 == []
|
in if refs == []
|
||||||
then throw ("Could not find " + file + " in " + packedRefsName)
|
then throw ("Could not find " + file + " in " + packedRefsName)
|
||||||
else lib.head (matchRef (lib.head refs))
|
else lib.head (matchRef (lib.head refs))
|
||||||
|
@ -157,7 +173,7 @@ rec {
|
||||||
else throw ("Not a .git directory: " + path);
|
else throw ("Not a .git directory: " + path);
|
||||||
in readCommitFromFile "HEAD";
|
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));
|
canCleanSource = src: src ? _isLibCleanSourceWith || !(pathHasContext (toString src));
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,10 +41,15 @@ Usage:
|
||||||
[1] maybe this behaviour should be removed to keep things simple (?)
|
[1] maybe this behaviour should be removed to keep things simple (?)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
with lib.lists;
|
let
|
||||||
with lib.attrsets;
|
inherit (lib)
|
||||||
with lib.strings;
|
concatStringsSep
|
||||||
|
head
|
||||||
|
isAttrs
|
||||||
|
listToAttrs
|
||||||
|
tail
|
||||||
|
;
|
||||||
|
in
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
/* !!! The interface of this function is kind of messed up, since
|
/* !!! The interface of this function is kind of messed up, since
|
||||||
|
|
|
@ -8,7 +8,29 @@ in
|
||||||
|
|
||||||
rec {
|
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.
|
/* Concatenate a list of strings.
|
||||||
|
|
||||||
|
@ -120,7 +142,7 @@ rec {
|
||||||
subDir:
|
subDir:
|
||||||
# List of base paths
|
# List of base paths
|
||||||
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
|
/* Construct a Unix-style search path by appending the given
|
||||||
`subDir` to the specified `output` of each of the packages. If no
|
`subDir` to the specified `output` of each of the packages. If no
|
||||||
|
@ -313,7 +335,7 @@ rec {
|
||||||
escapeNixString "hello\${}\n"
|
escapeNixString "hello\${}\n"
|
||||||
=> "\"hello\\\${}\\n\""
|
=> "\"hello\\\${}\\n\""
|
||||||
*/
|
*/
|
||||||
escapeNixString = s: escape ["$"] (builtins.toJSON s);
|
escapeNixString = s: escape ["$"] (toJSON s);
|
||||||
|
|
||||||
/* Turn a string into an exact regular expression
|
/* Turn a string into an exact regular expression
|
||||||
|
|
||||||
|
@ -337,7 +359,7 @@ rec {
|
||||||
*/
|
*/
|
||||||
escapeNixIdentifier = s:
|
escapeNixIdentifier = s:
|
||||||
# Regex from https://github.com/NixOS/nix/blob/d048577909e383439c2549e849c5c2f2016c997e/src/libexpr/lexer.l#L91
|
# 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;
|
then s else escapeNixString s;
|
||||||
|
|
||||||
# Obsolete - use replaceStrings instead.
|
# Obsolete - use replaceStrings instead.
|
||||||
|
@ -466,7 +488,7 @@ rec {
|
||||||
versionOlder "1.1" "1.1"
|
versionOlder "1.1" "1.1"
|
||||||
=> false
|
=> 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.
|
/* Return true if string v1 denotes a version equal to or newer than v2.
|
||||||
|
|
||||||
|
@ -492,7 +514,7 @@ rec {
|
||||||
*/
|
*/
|
||||||
getName = x:
|
getName = x:
|
||||||
let
|
let
|
||||||
parse = drv: (builtins.parseDrvName drv).name;
|
parse = drv: (parseDrvName drv).name;
|
||||||
in if isString x
|
in if isString x
|
||||||
then parse x
|
then parse x
|
||||||
else x.pname or (parse x.name);
|
else x.pname or (parse x.name);
|
||||||
|
@ -509,7 +531,7 @@ rec {
|
||||||
*/
|
*/
|
||||||
getVersion = x:
|
getVersion = x:
|
||||||
let
|
let
|
||||||
parse = drv: (builtins.parseDrvName drv).version;
|
parse = drv: (parseDrvName drv).version;
|
||||||
in if isString x
|
in if isString x
|
||||||
then parse x
|
then parse x
|
||||||
else x.version or (parse x.name);
|
else x.version or (parse x.name);
|
||||||
|
@ -527,7 +549,7 @@ rec {
|
||||||
let
|
let
|
||||||
components = splitString "/" url;
|
components = splitString "/" url;
|
||||||
filename = lib.last components;
|
filename = lib.last components;
|
||||||
name = builtins.head (splitString sep filename);
|
name = head (splitString sep filename);
|
||||||
in assert name != filename; name;
|
in assert name != filename; name;
|
||||||
|
|
||||||
/* Create an --{enable,disable}-<feat> string that can be passed to
|
/* Create an --{enable,disable}-<feat> string that can be passed to
|
||||||
|
@ -617,14 +639,14 @@ rec {
|
||||||
*/
|
*/
|
||||||
floatToString = float: let
|
floatToString = float: let
|
||||||
result = toString float;
|
result = toString float;
|
||||||
precise = float == builtins.fromJSON result;
|
precise = float == fromJSON result;
|
||||||
in if precise then result
|
in if precise then result
|
||||||
else lib.warn "Imprecise conversion from float to string ${result}" result;
|
else lib.warn "Imprecise conversion from float to string ${result}" result;
|
||||||
|
|
||||||
/* Check whether a value can be coerced to a string */
|
/* Check whether a value can be coerced to a string */
|
||||||
isCoercibleToString = x:
|
isCoercibleToString = x:
|
||||||
builtins.elem (builtins.typeOf x) [ "path" "string" "null" "int" "float" "bool" ] ||
|
elem (typeOf x) [ "path" "string" "null" "int" "float" "bool" ] ||
|
||||||
(builtins.isList x && lib.all isCoercibleToString x) ||
|
(isList x && lib.all isCoercibleToString x) ||
|
||||||
x ? outPath ||
|
x ? outPath ||
|
||||||
x ? __toString;
|
x ? __toString;
|
||||||
|
|
||||||
|
@ -643,8 +665,8 @@ rec {
|
||||||
isStorePath = x:
|
isStorePath = x:
|
||||||
if isCoercibleToString x then
|
if isCoercibleToString x then
|
||||||
let str = toString x; in
|
let str = toString x; in
|
||||||
builtins.substring 0 1 str == "/"
|
substring 0 1 str == "/"
|
||||||
&& dirOf str == builtins.storeDir
|
&& dirOf str == storeDir
|
||||||
else
|
else
|
||||||
false;
|
false;
|
||||||
|
|
||||||
|
@ -662,8 +684,8 @@ rec {
|
||||||
*/
|
*/
|
||||||
# Obviously, it is a bit hacky to use fromJSON this way.
|
# Obviously, it is a bit hacky to use fromJSON this way.
|
||||||
toInt = str:
|
toInt = str:
|
||||||
let may_be_int = builtins.fromJSON str; in
|
let may_be_int = fromJSON str; in
|
||||||
if builtins.isInt may_be_int
|
if isInt may_be_int
|
||||||
then may_be_int
|
then may_be_int
|
||||||
else throw "Could not convert ${str} to 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"
|
readPathsFromFile = lib.warn "lib.readPathsFromFile is deprecated, use a list instead"
|
||||||
(rootPath: file:
|
(rootPath: file:
|
||||||
let
|
let
|
||||||
lines = lib.splitString "\n" (builtins.readFile file);
|
lines = lib.splitString "\n" (readFile file);
|
||||||
removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line));
|
removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line));
|
||||||
relativePaths = removeComments lines;
|
relativePaths = removeComments lines;
|
||||||
absolutePaths = builtins.map (path: rootPath + "/${path}") relativePaths;
|
absolutePaths = map (path: rootPath + "/${path}") relativePaths;
|
||||||
in
|
in
|
||||||
absolutePaths);
|
absolutePaths);
|
||||||
|
|
||||||
|
@ -702,7 +724,7 @@ rec {
|
||||||
fileContents ./version
|
fileContents ./version
|
||||||
=> "1.0"
|
=> "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.
|
/* Creates a valid derivation name from a potentially invalid one.
|
||||||
|
@ -720,13 +742,13 @@ rec {
|
||||||
sanitizeDerivationName = string: lib.pipe string [
|
sanitizeDerivationName = string: lib.pipe string [
|
||||||
# Get rid of string context. This is safe under the assumption that the
|
# Get rid of string context. This is safe under the assumption that the
|
||||||
# resulting string is only used as a derivation name
|
# resulting string is only used as a derivation name
|
||||||
builtins.unsafeDiscardStringContext
|
unsafeDiscardStringContext
|
||||||
# Strip all leading "."
|
# Strip all leading "."
|
||||||
(x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0)
|
(x: elemAt (match "\\.*(.*)" x) 0)
|
||||||
# Split out all invalid characters
|
# 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/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
|
# 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 "-"
|
# Replace invalid character ranges with a "-"
|
||||||
(concatMapStrings (s: if lib.isList s then "-" else s))
|
(concatMapStrings (s: if lib.isList s then "-" else s))
|
||||||
# Limit to 211 characters (minus 4 chars for ".drv")
|
# Limit to 211 characters (minus 4 chars for ".drv")
|
||||||
|
|
|
@ -1,12 +1,62 @@
|
||||||
# Definitions related to run-time type checking. Used in particular
|
# Definitions related to run-time type checking. Used in particular
|
||||||
# to type-check NixOS configurations.
|
# to type-check NixOS configurations.
|
||||||
{ lib }:
|
{ lib }:
|
||||||
with lib.lists;
|
|
||||||
with lib.attrsets;
|
|
||||||
with lib.options;
|
|
||||||
with lib.trivial;
|
|
||||||
with lib.strings;
|
|
||||||
let
|
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;
|
inherit (lib.modules) mergeDefinitions;
|
||||||
outer_types =
|
outer_types =
|
||||||
|
@ -270,7 +320,7 @@ rec {
|
||||||
name = "attrs";
|
name = "attrs";
|
||||||
description = "attribute set";
|
description = "attribute set";
|
||||||
check = isAttrs;
|
check = isAttrs;
|
||||||
merge = loc: foldl' (res: def: mergeAttrs res def.value) {};
|
merge = loc: foldl' (res: def: res // def.value) {};
|
||||||
emptyValue = { value = {}; };
|
emptyValue = { value = {}; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue