aboutsummaryrefslogtreecommitdiff
path: root/lib/filesystem.nix
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2017-03-04 13:15:23 -0500
committerShea Levy <shea@shealevy.com>2017-03-04 13:15:23 -0500
commit56e71f62dc49e64fcd37768cc7d1ec219d4990e6 (patch)
tree7e91a13dface2b09b4574447eaa8e5c5ec3b916c /lib/filesystem.nix
parent7b914b29864132ae73e4a0eb9656eec8bb05102f (diff)
Add locateDominatingFile lib function
Diffstat (limited to 'lib/filesystem.nix')
-rw-r--r--lib/filesystem.nix26
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/filesystem.nix b/lib/filesystem.nix
new file mode 100644
index 000000000000..91b04d81c13b
--- /dev/null
+++ b/lib/filesystem.nix
@@ -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);
+}