diff --git a/default.nix b/default.nix index 1cfc5b2..97b875a 100644 --- a/default.nix +++ b/default.nix @@ -60,16 +60,6 @@ let leaves = let - listFilesRecursive = - x: - if isImportTree x then - x.files - else if hasOutPath x then - listFilesRecursive x.outPath - else if isDirectory x then - listDirFilesRecursive x - else - [ x ]; nixFilter = andNot (hasInfix "/_") (hasSuffix ".nix"); @@ -79,43 +69,29 @@ let otherFilter = and filterf (if initf != null then initf else (_: true)); - filter = x: if isPathLike x then pathFilter x else otherFilter x; - - isFileRelative = - root: - { file, rel }: - if file != null && hasPrefix root file then - { - file = null; - rel = removePrefix root file; - } + # Filter an explicit user supplied path: + filterFiles = + x: + if hasOutPath x then + filterFiles x.outPath + else if isImportTree x then + # Use the foreign import-tree filtering so that relative path are correctly handled: + (x.filter filterf).files + else if isPathLike x then + if builtins.readFileType x == "directory" then + let + dir = toString x; + # Apply pathFilter to relative path from the user-supplied directory: + relativize = file: removePrefix dir (toString file); + in + builtins.filter (compose pathFilter relativize) (listDirFilesRecursive x) + else + # For explicit user-supplied (non-directory) files, ignore filter: + x + else if otherFilter x then + x else - { inherit file rel; }; - getFileRelative = { file, rel }: if rel == null then file else rel; - - # Strip the first matching root-directory prefix from a file, yielding a - # path relative to that root (or the file itself if none match). Folds the - # `{ file, rel }` state directly over the roots — once a root matches, - # `file` becomes null and later roots are no-ops. - makeRelative = - roots: - let - dirs = builtins.map builtins.toString (builtins.filter isDirectory (flatten roots)); - in - file: - getFileRelative ( - builtins.foldl' (acc: root: isFileRelative root acc) { - file = builtins.toString file; - rel = null; - } dirs - ); - - rootRelative = - roots: - let - mkRel = makeRelative roots; - in - x: if isPathLike x then mkRel x else x; + [ ]; in root: let @@ -123,13 +99,9 @@ let paths root ]; - files = flatten (map listFilesRecursive roots); - relativize = rootRelative [ - paths - root - ]; + files = flatten (map filterFiles roots); in - map mapf (builtins.filter (compose filter relativize) files); + map mapf files; in result; @@ -139,9 +111,6 @@ let # lib.lists.flatten flatten = x: if builtins.isList x then builtins.concatMap flatten x else [ x ]; - # lib.strings.hasPrefix - hasPrefix = pre: s: builtins.substring 0 (builtins.stringLength pre) s == pre; - # lib.strings.removePrefix removePrefix = pre: s: @@ -207,8 +176,6 @@ let attrs: k: f: attrs // { ${k} = f attrs.${k}; }; - isDirectory = and (x: builtins.readFileType x == "directory") isPathLike; - isPathLike = x: builtins.isPath x || builtins.isString x || hasOutPath x; hasOutPath = and (x: x ? outPath) builtins.isAttrs; @@ -232,7 +199,7 @@ let initial = { # Accumulated configuration api = { }; - mapf = (i: i); + mapf = i: i; filterf = _: true; paths = [ ]; scoped = { }; @@ -277,11 +244,11 @@ let withLib = _lib: mergeAttrs { }; initFilter = initf: mergeAttrs { inherit initf; }; pipeTo = pipef: mergeAttrs { inherit pipef; }; - leaves = mergeAttrs { pipef = (i: i); }; + leaves = mergeAttrs { pipef = i: i; }; leafs = builtins.warn "import-tree.leafs has been deprecated. Use import-tree.leaves instead." (mergeAttrs { - pipef = (i: i); + pipef = i: i; }); # Applies empty (for already path-configured trees) diff --git a/tests.nix b/tests.nix index f65cffd..30fda88 100644 --- a/tests.nix +++ b/tests.nix @@ -254,6 +254,17 @@ in ]; }; + import-tree."test can take other import-trees as if they were paths - hidden paths variant" = { + expr = lit.leaves [ + (it.addPath [ ./tree/a/b/_c ]) + ./tree/modules/hello-world + ]; + expected = [ + ./tree/a/b/_c/d/e.nix + ./tree/modules/hello-world/mod.nix + ]; + }; + import-tree."test can be used in submodule" = { expr = (lib.evalModules { @@ -275,6 +286,11 @@ in expected = [ ./tree/a/b/_c/d/e.nix ]; }; + leaves."test loads root file from hidden directory" = { + expr = lit.leaves ./tree/a/b/_c/d/e.nix; + expected = [ ./tree/a/b/_c/d/e.nix ]; + }; + scoped."test adds attrs via scopedImport" = { expr = (lib.evalModules {