Add locateDominatingFile lib function

This commit is contained in:
Shea Levy 2017-03-04 13:15:23 -05:00
parent 7b914b2986
commit 56e71f62dc
2 changed files with 30 additions and 1 deletions

View File

@ -34,6 +34,9 @@ let
sandbox = import ./sandbox.nix; sandbox = import ./sandbox.nix;
fetchers = import ./fetchers.nix; fetchers = import ./fetchers.nix;
# Eval-time filesystem handling
filesystem = import ./filesystem.nix;
in in
{ inherit trivial { inherit trivial
attrsets lists strings stringsWithDeps attrsets lists strings stringsWithDeps
@ -41,7 +44,7 @@ in
modules options types modules options types
licenses platforms systems licenses platforms systems
debug generators misc debug generators misc
sandbox fetchers; sandbox fetchers filesystem;
} }
# !!! don't include everything at top-level; perhaps only the most # !!! don't include everything at top-level; perhaps only the most
# commonly used functions. # commonly used functions.

26
lib/filesystem.nix Normal file
View File

@ -0,0 +1,26 @@
{ # locateDominatingFile : RegExp
# -> Path
# -> Nullable { path : Path;
# matches : [ MatchResults ];
# }
# Find the first directory containing a file matching 'pattern'
# upward from a given 'file'.
# Returns 'null' if no directories contain a file matching 'pattern'.
locateDominatingFile = pattern: file:
let go = path:
let files = builtins.attrNames (builtins.readDir path);
matches = builtins.filter (match: match != null)
(map (builtins.match pattern) files);
in
if builtins.length matches != 0
then { inherit path matches; }
else if path == /.
then null
else go (dirOf path);
parent = dirOf file;
isDir =
let base = baseNameOf file;
type = (builtins.readDir parent).${base} or null;
in file == /. || type == "directory";
in go (if isDir then file else parent);
}