|
|
|
@ -1,10 +1,14 @@ |
|
|
|
|
{ lib ? import <nixpkgs/lib> }: |
|
|
|
|
{ pkgs ? import <nixpkgs> {} }: |
|
|
|
|
let |
|
|
|
|
inherit (builtins) baseNameOf dirOf length genList pathExists filterSource |
|
|
|
|
isString match replaceStrings stringLength; |
|
|
|
|
inherit (lib) take splitString concatStringsSep last foldl foldr head tail |
|
|
|
|
singleton removePrefix hasSuffix removeSuffix flatten crossLists reverseList |
|
|
|
|
all any unique hasPrefix; |
|
|
|
|
lib = pkgs.lib; |
|
|
|
|
inherit (builtins) baseNameOf dirOf length genList pathExists isString match |
|
|
|
|
replaceStrings; |
|
|
|
|
inherit (lib) take splitString last foldl foldr head tail removePrefix |
|
|
|
|
hasSuffix removeSuffix flatten crossLists reverseList all any unique hasPrefix |
|
|
|
|
cleanSourceWith; |
|
|
|
|
|
|
|
|
|
inherit (pkgs) runCommand symlinkJoin; |
|
|
|
|
|
|
|
|
|
butlast = list: take (length list - 1) list; |
|
|
|
|
|
|
|
|
|
doFileSuffix = "do"; |
|
|
|
@ -83,14 +87,27 @@ let |
|
|
|
|
# The source tree resolver combinator. |
|
|
|
|
# Takes the source root and cwd of the current builder and a list of paths |
|
|
|
|
# that shall always be rejected. |
|
|
|
|
# Also takes a resolver to derive unknown paths and a function to which the |
|
|
|
|
# resulting set is applied to. |
|
|
|
|
# |
|
|
|
|
# Returns a filter that accepts zero to n paths relative to cwd. Captures the |
|
|
|
|
# whole source tree when called with zero arguments. |
|
|
|
|
getSrc = root: rcwd: rejected: outFunc: |
|
|
|
|
getSrc = root: rcwd: rejected: resolver: outFunc: |
|
|
|
|
captureFunc (resolveSrc root rcwd) (srcs: let |
|
|
|
|
|
|
|
|
|
rejector = path: (all (x: path != x) rejected); |
|
|
|
|
|
|
|
|
|
# Filter non-existant sources and build them with resolver. |
|
|
|
|
# Recreate the source directory structure. |
|
|
|
|
nonExistantSrcs = builtins.filter (x: !builtins.pathExists x) srcs; |
|
|
|
|
builtSrcs = map (s: let |
|
|
|
|
relPath = removePrefix (root + "/") s; |
|
|
|
|
filePath = resolver s; |
|
|
|
|
in runCommand relPath { preferLocalBuild = true; allowSubstitutes = false; } '' |
|
|
|
|
mkdir -p "$out/${dirOf relPath}" |
|
|
|
|
ln -s "${filePath}" "$out/${relPath}" |
|
|
|
|
'') nonExistantSrcs; |
|
|
|
|
|
|
|
|
|
# If a src in srcs is a prefix to a that (it must be a dir, then, or the |
|
|
|
|
# file itself), allow all sub-paths. |
|
|
|
|
srcFilter = path: |
|
|
|
@ -103,13 +120,21 @@ let |
|
|
|
|
srcDirFilter = path: if srcs == [] |
|
|
|
|
then true # No explicit srcs means: Take the whole source tree! |
|
|
|
|
else (any (x: path == x) (_srcs)); |
|
|
|
|
|
|
|
|
|
# Filter the sources by our defined criteria and create a source tree |
|
|
|
|
# derivation. |
|
|
|
|
filter = (path: type: |
|
|
|
|
(baseNameOf path != ".git") && |
|
|
|
|
(baseNameOf path != ".envrc") && |
|
|
|
|
(rejector path) && |
|
|
|
|
((srcFilter path) || |
|
|
|
|
(srcDirFilter path))); |
|
|
|
|
in outFunc (builtins.filterSource filter root)); |
|
|
|
|
filteredSrcs = cleanSourceWith { inherit filter; src = root; }; |
|
|
|
|
|
|
|
|
|
# Merge the filtered sources and the newly built dependencies. |
|
|
|
|
mergedSrcs = symlinkJoin { name = "srcs"; paths = [ filteredSrcs ] ++ builtSrcs; }; |
|
|
|
|
|
|
|
|
|
in outFunc mergedSrcs); |
|
|
|
|
|
|
|
|
|
self = { |
|
|
|
|
inherit doFileSuffix whichdo d1 d2 getSrc; |
|
|
|
|