2 Functions for querying information about the filesystem
3 without copying any files to the Nix store.
7 # Tested in lib/tests/filesystem.sh
14 inherit (lib.filesystem)
22 The type of a path. The path needs to exist and be accessible.
23 The result is either "directory" for a directory, "regular" for a regular file, "symlink" for a symlink, or "unknown" for anything else.
26 pathType :: Path -> String
32 pathType /some/file.nix
36 builtins.readFileType or
37 # Nix <2.14 compatibility shim
40 # Fail irrecoverably to mimic the historic behavior of this function and
41 # the new builtins.readFileType
42 then abort "lib.filesystem.pathType: Path ${toString path} does not exist."
43 # The filesystem root is the only path where `dirOf / == /` and
44 # `baseNameOf /` is not valid. We can detect this and directly return
45 # "directory", since we know the filesystem root can't be anything else.
46 else if dirOf path == path
48 else (readDir (dirOf path)).${baseNameOf path}
52 Whether a path exists and is a directory.
55 pathIsDirectory :: Path -> Bool
61 pathIsDirectory /this/does/not/exist
64 pathIsDirectory /some/file.nix
67 pathIsDirectory = path:
68 pathExists path && pathType path == "directory";
71 Whether a path exists and is a regular file, meaning not a symlink or any other special file type.
74 pathIsRegularFile :: Path -> Bool
80 pathIsRegularFile /this/does/not/exist
83 pathIsRegularFile /some/file.nix
86 pathIsRegularFile = path:
87 pathExists path && pathType path == "regular";
90 A map of all haskell packages defined in the given path,
91 identified by having a cabal file with the same name as the
94 Type: Path -> Map String Path
97 # The directory within to search
99 let # Files in the root
100 root-files = builtins.attrNames (builtins.readDir root);
101 # Files with their full paths
102 root-files-with-paths =
104 { name = file; value = root + "/${file}"; }
106 # Subdirectories of the root with a cabal file.
108 builtins.filter ({ name, value }:
109 builtins.pathExists (value + "/${name}.cabal")
110 ) root-files-with-paths;
111 in builtins.listToAttrs cabal-subdirs;
113 Find the first directory containing a file matching 'pattern'
114 upward from a given 'file'.
115 Returns 'null' if no directories contain a file matching 'pattern'.
117 Type: RegExp -> Path -> Nullable { path : Path; matches : [ MatchResults ]; }
119 locateDominatingFile =
120 # The pattern to search for
122 # The file to start searching upward from
125 let files = builtins.attrNames (builtins.readDir path);
126 matches = builtins.filter (match: match != null)
127 (map (builtins.match pattern) files);
129 if builtins.length matches != 0
130 then { inherit path matches; }
133 else go (dirOf path);
136 let base = baseNameOf file;
137 type = (builtins.readDir parent).${base} or null;
138 in file == /. || type == "directory";
139 in go (if isDir then file else parent);
143 Given a directory, return a flattened list of all files within it recursively.
145 Type: Path -> [ Path ]
148 # The path to recursively list
150 lib.flatten (lib.mapAttrsToList (name: type:
151 if type == "directory" then
152 lib.filesystem.listFilesRecursive (dir + "/${name}")
155 ) (builtins.readDir dir));