from collections import defaultdict from dataclasses import dataclass, field from os import path from typing import List, Set @dataclass class Directory: files: List[str] = field(default_factory=list) subfolders: Set[str] = field(default_factory=set) def _find_files(extensions, repository): patterns = (f'**.{ext}' for ext in extensions) zero = '\x00' return repository.git.ls_files('-z', *patterns).strip(zero).split(zero) def _fill_directories(files, top_dir): directories = defaultdict(Directory) for f in files: fdir, fname = path.split(f) directories[fdir].files.append(fname) if fdir: parent, child = path.split(fdir) directories[parent].subfolders.add(child) return directories def compute_directories(extensions, repository): files = _find_files(extensions, repository) top_dir = path.relpath(repository.working_dir, path.curdir) return _fill_directories(files, top_dir)