Created
August 7, 2020 19:17
-
-
Save mminer/0dac886b4584bda87f2d117243fd492f to your computer and use it in GitHub Desktop.
Gets the "minimal" paths that comprise a directory's contents while excluding a set of child paths.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def get_minimal_paths(root_directory, paths_to_exclude=None, paths_to_include=None): | |
""" | |
Gets the "minimal" paths that comprise a directory's contents while excluding a set of child paths. | |
For example, given this directory hierarchy: | |
C:/Engine | |
Binaries | |
Documentation | |
Plugins | |
2D | |
FX | |
Media | |
And excluding paths "Documentation" and "Plugins/FX", the result would be: | |
[ | |
"Binaries", | |
"Plugins/2D", | |
"Plugins/Media", | |
] | |
If paths to include are passed, it and all its siblings are added to the result. | |
""" | |
minimal_paths = set(os.listdir(rootDirectory)) | |
paths_to_exclude = paths_to_exclude or [] | |
paths_to_exclude = [os.path.normpath(path) for path in paths_to_exclude] | |
paths_to_include = paths_to_include or [] | |
paths_to_include = [os.path.normpath(path) for path in paths_to_include] | |
def replace_path_parents_with_siblings(target_path): | |
""" | |
If a parent of the path is present, replace it with all its child directories. | |
Continue until no parent paths remain in the set. | |
""" | |
while True: | |
parent_path = next((path for path in minimal_paths | |
if target_path.startswith(path) and path != target_path), None) | |
if not parent_path: | |
return | |
absolute_parent_path = os.path.join(root_directory, parent_path) | |
child_paths = [os.path.join(parent_path, directory) | |
for directory in os.listdir(absolute_parent_path)] | |
child_paths = [path for path in child_paths | |
if path not in paths_to_exclude] | |
minimal_paths.remove(parent_path) | |
minimal_paths.update(child_paths) | |
for path in paths_to_exclude: | |
replace_path_parents_with_siblings(path) | |
for path in paths_to_include: | |
minimal_paths.add(path) | |
replace_path_parents_with_siblings(path) | |
return sorted(minimal_paths) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment