Skip to content

Instantly share code, notes, and snippets.

@mminer
Created August 7, 2020 19:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mminer/0dac886b4584bda87f2d117243fd492f to your computer and use it in GitHub Desktop.
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.
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