lib.sources: small performance improvements (#536129)
This commit is contained in:
+78
-50
@@ -4,22 +4,31 @@
|
||||
# Tested in lib/tests/sources.sh
|
||||
let
|
||||
inherit (lib.strings)
|
||||
match
|
||||
split
|
||||
storeDir
|
||||
escapeRegex
|
||||
hasPrefix
|
||||
hasSuffix
|
||||
match
|
||||
removePrefix
|
||||
removeSuffix
|
||||
split
|
||||
splitString
|
||||
storeDir
|
||||
stringLength
|
||||
substring
|
||||
;
|
||||
inherit (lib)
|
||||
boolToString
|
||||
filter
|
||||
isString
|
||||
readFile
|
||||
concatStrings
|
||||
length
|
||||
elemAt
|
||||
isList
|
||||
any
|
||||
boolToString
|
||||
concatStrings
|
||||
elemAt
|
||||
fileContents
|
||||
filter
|
||||
head
|
||||
isList
|
||||
isString
|
||||
last
|
||||
length
|
||||
readFile
|
||||
;
|
||||
inherit (lib.filesystem)
|
||||
pathIsRegularFile
|
||||
@@ -41,6 +50,12 @@ let
|
||||
: 2\. Function argument
|
||||
*/
|
||||
cleanSourceFilter =
|
||||
let
|
||||
hasEmacsBackupFileSuffix = hasSuffix "~";
|
||||
hasObjectSuffix = hasSuffix ".o";
|
||||
hasSharedObjectSuffix = hasSuffix ".so";
|
||||
hasResultPrefix = hasPrefix "result";
|
||||
in
|
||||
name: type:
|
||||
let
|
||||
baseName = baseNameOf name;
|
||||
@@ -62,17 +77,15 @@ let
|
||||
)
|
||||
||
|
||||
# Filter out editor backup / swap files.
|
||||
lib.hasSuffix "~" baseName
|
||||
hasEmacsBackupFileSuffix baseName
|
||||
|| match "^\\.sw[a-z]$" baseName != null
|
||||
|| match "^\\..*\\.sw[a-z]$" baseName != null
|
||||
||
|
||||
|
||||
# Filter out generates files.
|
||||
lib.hasSuffix ".o" baseName
|
||||
|| lib.hasSuffix ".so" baseName
|
||||
# Filter out generated files.
|
||||
|| hasObjectSuffix baseName
|
||||
|| hasSharedObjectSuffix baseName
|
||||
||
|
||||
# Filter out nix-build result symlinks
|
||||
(type == "symlink" && lib.hasPrefix "result" baseName)
|
||||
(type == "symlink" && hasResultPrefix baseName)
|
||||
||
|
||||
# Filter out sockets and other types of files we can't have in the store.
|
||||
(type == "unknown")
|
||||
@@ -133,13 +146,13 @@ let
|
||||
{
|
||||
# A path or cleanSourceWith result to filter and/or rename.
|
||||
src,
|
||||
# Optional with default value: constant true (include everything)
|
||||
# Optional with default value of null (include everything)
|
||||
# The function will be combined with the && operator such
|
||||
# that src.filter is called lazily.
|
||||
# For implementing a filter, see
|
||||
# https://nixos.org/nix/manual/#builtin-filterSource
|
||||
# Type: A function (Path -> Type -> Bool)
|
||||
filter ? _path: _type: true,
|
||||
filter ? null,
|
||||
# Optional name to use as part of the store path.
|
||||
# This defaults to `src.name` or otherwise `"source"`.
|
||||
name ? null,
|
||||
@@ -149,7 +162,13 @@ let
|
||||
in
|
||||
fromSourceAttributes {
|
||||
inherit (orig) origSrc;
|
||||
filter = path: type: filter path type && orig.filter path type;
|
||||
filter =
|
||||
if orig.filter == null then
|
||||
filter
|
||||
else if filter == null then
|
||||
orig.filter
|
||||
else
|
||||
path: type: filter path type && orig.filter path type;
|
||||
name = if name != null then name else orig.name;
|
||||
};
|
||||
|
||||
@@ -178,11 +197,14 @@ let
|
||||
attrs
|
||||
// {
|
||||
filter =
|
||||
path: type:
|
||||
let
|
||||
r = attrs.filter path type;
|
||||
in
|
||||
builtins.trace "${attrs.name}.filter ${path} = ${boolToString r}" r;
|
||||
if attrs.filter == null then
|
||||
path: type: builtins.trace "${attrs.name}.filter ${path} = true" true
|
||||
else
|
||||
path: type:
|
||||
let
|
||||
r = attrs.filter path type;
|
||||
in
|
||||
builtins.trace "${attrs.name}.filter ${path} = ${boolToString r}" r;
|
||||
}
|
||||
)
|
||||
// {
|
||||
@@ -218,13 +240,13 @@ let
|
||||
isFiltered = src ? _isLibCleanSourceWith;
|
||||
origSrc = if isFiltered then src.origSrc else src;
|
||||
in
|
||||
lib.cleanSourceWith {
|
||||
cleanSourceWith {
|
||||
filter = (
|
||||
path: type:
|
||||
let
|
||||
relPath = lib.removePrefix (toString origSrc + "/") (toString path);
|
||||
relPath = removePrefix (toString origSrc + "/") (toString path);
|
||||
in
|
||||
lib.any (re: match re relPath != null) regexes
|
||||
any (re: match re relPath != null) regexes
|
||||
);
|
||||
inherit src;
|
||||
};
|
||||
@@ -272,7 +294,7 @@ let
|
||||
let
|
||||
base = baseNameOf name;
|
||||
in
|
||||
type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
|
||||
type == "directory" || any (ext: hasSuffix ext base) exts;
|
||||
in
|
||||
cleanSourceWith { inherit filter src; };
|
||||
|
||||
@@ -319,9 +341,9 @@ let
|
||||
packedRefsName = path + "/packed-refs";
|
||||
absolutePath =
|
||||
base: path:
|
||||
if lib.hasPrefix "/" path then
|
||||
if hasPrefix "/" path then
|
||||
path
|
||||
else if lib.hasPrefix "/" base then
|
||||
else if hasPrefix "/" base then
|
||||
"${base}/${path}"
|
||||
else
|
||||
"/${base}/${path}";
|
||||
@@ -337,12 +359,12 @@ let
|
||||
{ error = "File contains no gitdir reference: " + path; }
|
||||
else
|
||||
let
|
||||
gitDir = absolutePath (dirOf path) (lib.head m);
|
||||
gitDir = absolutePath (dirOf path) (head m);
|
||||
commonDir'' =
|
||||
if pathIsRegularFile "${gitDir}/commondir" then lib.fileContents "${gitDir}/commondir" else gitDir;
|
||||
commonDir' = lib.removeSuffix "/" commonDir'';
|
||||
if pathIsRegularFile "${gitDir}/commondir" then fileContents "${gitDir}/commondir" else gitDir;
|
||||
commonDir' = removeSuffix "/" commonDir'';
|
||||
commonDir = absolutePath gitDir commonDir';
|
||||
refFile = lib.removePrefix "${commonDir}/" "${gitDir}/${file}";
|
||||
refFile = removePrefix "${commonDir}/" "${gitDir}/${file}";
|
||||
in
|
||||
readCommitFromFile refFile commonDir
|
||||
|
||||
@@ -352,10 +374,10 @@ let
|
||||
# sometimes it stores something like: «ref: refs/heads/branch-name»
|
||||
then
|
||||
let
|
||||
fileContent = lib.fileContents fileName;
|
||||
fileContent = fileContents fileName;
|
||||
matchRef = match "^ref: (.*)$" fileContent;
|
||||
in
|
||||
if matchRef == null then { value = fileContent; } else readCommitFromFile (lib.head matchRef) path
|
||||
if matchRef == null then { value = fileContent; } else readCommitFromFile (head matchRef) path
|
||||
|
||||
else if
|
||||
pathIsRegularFile packedRefsName
|
||||
@@ -373,14 +395,14 @@ let
|
||||
if refs == [ ] then
|
||||
{ error = "Could not find " + file + " in " + packedRefsName; }
|
||||
else
|
||||
{ value = lib.head (matchRef (lib.head refs)); }
|
||||
{ value = head (matchRef (head refs)); }
|
||||
|
||||
else
|
||||
{ error = "Not a .git directory: " + toString path; };
|
||||
in
|
||||
readCommitFromFile "HEAD";
|
||||
|
||||
pathHasContext = builtins.hasContext or (lib.hasPrefix storeDir);
|
||||
pathHasContext = builtins.hasContext or (hasPrefix storeDir);
|
||||
|
||||
canCleanSource = src: src ? _isLibCleanSourceWith || !(pathHasContext (toString src));
|
||||
|
||||
@@ -403,7 +425,7 @@ let
|
||||
{
|
||||
# The original path
|
||||
origSrc = if isFiltered then src.origSrc else src;
|
||||
filter = if isFiltered then src.filter else _: _: true;
|
||||
filter = if isFiltered then src.filter else null; # make sure to handle this!
|
||||
name = if isFiltered then src.name else "source";
|
||||
};
|
||||
|
||||
@@ -411,6 +433,9 @@ let
|
||||
#
|
||||
# Inverse of toSourceAttributes for Source objects.
|
||||
fromSourceAttributes =
|
||||
let
|
||||
inherit (builtins) path;
|
||||
in
|
||||
{
|
||||
origSrc,
|
||||
filter,
|
||||
@@ -418,9 +443,13 @@ let
|
||||
}:
|
||||
{
|
||||
_isLibCleanSourceWith = true;
|
||||
inherit origSrc filter name;
|
||||
outPath = builtins.path {
|
||||
inherit filter name;
|
||||
inherit origSrc name;
|
||||
# preserve outside checks, since a filter of null looks odd for
|
||||
# comparisons
|
||||
filter = if filter == null then _: _: true else filter;
|
||||
outPath = path {
|
||||
inherit name;
|
||||
${if filter != null then "filter" else null} = filter;
|
||||
path = origSrc;
|
||||
};
|
||||
};
|
||||
@@ -431,15 +460,14 @@ let
|
||||
urlToName =
|
||||
url:
|
||||
let
|
||||
inherit (lib.strings) stringLength;
|
||||
base = baseNameOf (lib.removeSuffix "/" (lib.last (lib.splitString ":" (toString url))));
|
||||
base = baseNameOf (removeSuffix "/" (last (splitString ":" (toString url))));
|
||||
# chop away one git or archive-related extension
|
||||
removeExt =
|
||||
name:
|
||||
let
|
||||
matchExt = match "(.*)\\.(git|tar|zip|gz|tgz|bz|tbz|bz2|tbz2|lzma|txz|xz|zstd)$" name;
|
||||
in
|
||||
if matchExt != null then lib.head matchExt else name;
|
||||
if matchExt != null then head matchExt else name;
|
||||
# apply function f to string x while the result shrinks
|
||||
shrink =
|
||||
f: x:
|
||||
@@ -461,9 +489,9 @@ let
|
||||
matchVer = match "([A-Za-z]+[-_. ]?)*(v)?([0-9.]+.*)" baseRev;
|
||||
in
|
||||
if matchHash != null then
|
||||
builtins.substring 0 7 baseRev
|
||||
substring 0 7 baseRev
|
||||
else if matchVer != null then
|
||||
lib.last matchVer
|
||||
last matchVer
|
||||
else
|
||||
baseRev;
|
||||
|
||||
@@ -623,7 +651,7 @@ let
|
||||
|
||||
in
|
||||
src: patterns:
|
||||
lib.cleanSourceWith {
|
||||
cleanSourceWith {
|
||||
filter = mkSourceFilter src patterns;
|
||||
inherit src;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user