diff --git a/lib/sources.nix b/lib/sources.nix index 81b8a8c77178..9846e9c586f7 100644 --- a/lib/sources.nix +++ b/lib/sources.nix @@ -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; };