Coverage for tools / sel_tools / utils / files.py: 100%
27 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-02 18:55 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-02 18:55 +0000
1"""File utils for software engineering tools."""
3from abc import ABCMeta, abstractmethod
4from pathlib import Path
6CMAKELISTS_FILE_NAME = "CMakeLists.txt"
9class FileVisitor:
10 """Interface for file visitor.
12 Children implement visit_file
13 """
15 __metaclass__ = ABCMeta
17 @abstractmethod
18 def visit_file(self, file: Path) -> None:
19 msg = "Don't call me, I'm abstract."
20 raise NotImplementedError(msg)
23class FileTree:
24 """Caller of the visitor pattern.
26 Accepts visitors on it is file tree, applies FileVisitor.visit_file() to each
27 file in item
28 """
30 def __init__(self, item: Path) -> None:
31 self._item = item
33 def accept(self, visitor: FileVisitor) -> None:
34 if self._item.is_file():
35 visitor.visit_file(self._item)
36 elif self._item.is_dir():
37 for sub_item in self.rglob_but(".git"):
38 if sub_item.is_file():
39 visitor.visit_file(sub_item)
40 else:
41 msg = f"Path {self._item} does not exist"
42 raise FileNotFoundError(msg)
44 def rglob_but(self, ignore_folder: str) -> list[Path]:
45 return sorted(
46 set(self._item.rglob("*"))
47 - set(self._item.rglob(ignore_folder))
48 - set((self._item / ignore_folder).rglob("*"))
49 )
52def is_cmake(file: Path) -> bool:
53 """Return true if the file is a cmake file, otherwise false."""
54 return (file.name == CMAKELISTS_FILE_NAME) or (file.suffix == ".cmake")
57def is_cpp(file: Path) -> bool:
58 """Return true if the file is a cpp file, otherwise false."""
59 return file.suffix in [".cpp", ".h", ".hpp"]