Add llnl.util.filesystem.find_first (#36083)

Add a `find_first` method that locates one instance of a file
that matches a specified pattern by recursively searching a directory
tree. Unlike other `find` methods, this only locates one file at most,
so can use optimizations that avoid searching the entire tree:
Typically the relevant files are at low depth, so it makes sense to
locate files through iterative deepening and early exit.
This commit is contained in:
Harmen Stoppels
2023-03-27 18:42:16 +02:00
committed by GitHub
parent c5b3fc6929
commit 5072e48dab
2 changed files with 168 additions and 1 deletions

View File

@@ -871,3 +871,34 @@ def test_filesummary(tmpdir):
assert fs.filesummary(p, print_bytes=8) == (26, b"abcdefgh...stuvwxyz")
assert fs.filesummary(p, print_bytes=13) == (26, b"abcdefghijklmnopqrstuvwxyz")
assert fs.filesummary(p, print_bytes=100) == (26, b"abcdefghijklmnopqrstuvwxyz")
@pytest.mark.parametrize("bfs_depth", [1, 2, 10])
def test_find_first_file(tmpdir, bfs_depth):
# Create a structure: a/a/a/{file1,file2}, b/a, c/a, d/{a,file1}
tmpdir.join("a", "a", "a").ensure(dir=True)
tmpdir.join("b", "a").ensure(dir=True)
tmpdir.join("c", "a").ensure(dir=True)
tmpdir.join("d", "a").ensure(dir=True)
tmpdir.join("e").ensure(dir=True)
fs.touch(tmpdir.join("a", "a", "a", "file1"))
fs.touch(tmpdir.join("a", "a", "a", "file2"))
fs.touch(tmpdir.join("d", "file1"))
root = str(tmpdir)
# Iterative deepening: should find low-depth file1.
assert os.path.samefile(
fs.find_first(root, "file*", bfs_depth=bfs_depth), os.path.join(root, "d", "file1")
)
assert fs.find_first(root, "nonexisting", bfs_depth=bfs_depth) is None
assert os.path.samefile(
fs.find_first(root, ["nonexisting", "file2"], bfs_depth=bfs_depth),
os.path.join(root, "a", "a", "a", "file2"),
)
# Should find first dir
assert os.path.samefile(fs.find_first(root, "a", bfs_depth=bfs_depth), os.path.join(root, "a"))