Created
June 15, 2022 08:54
-
-
Save macleginn/e317135b04e8ae21d4ed29a7760c939b to your computer and use it in GitHub Desktop.
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
import os | |
import sys | |
import shutil | |
def copy_tree(src, dst): | |
''' | |
Copy a directory tree from src to dst ignoring dangling | |
symlinks, retrieving files symlinks point to, and | |
breaking the cycles, i.e. never copying the same | |
source file twice. | |
''' | |
os.mkdir(dst) | |
visited_source_paths = set() | |
stack = [] | |
for item in os.listdir(src): | |
stack.append(item) | |
while stack: | |
current_path_suffix = stack.pop() | |
current_path = os.path.join(src, current_path_suffix) | |
print(current_path) | |
if os.path.realpath(current_path) in visited_source_paths: | |
continue | |
if os.path.islink(current_path): | |
realpath = os.path.realpath(current_path) | |
print(f'-> {realpath}') | |
# Skip dangling and circular symlinks. | |
if not os.path.exists(realpath) or realpath in visited_source_paths: | |
continue | |
# We assume for simplicity that the stuff valid symlinks point to is valid. | |
shutil.copytree(realpath, os.path.join( | |
dst, current_path_suffix), ignore=shutil.ignore_patterns('*.pyc')) | |
elif os.path.isdir(current_path): | |
# Create the directory in the destination tree, | |
# add the contents to the stack, and continue. | |
os.mkdir(os.path.join(dst, current_path_suffix)) | |
for item in os.listdir(current_path): | |
stack.append(os.path.join(current_path_suffix, item)) | |
else: | |
# A simple file. | |
if not current_path.endswith('.pyc'): | |
shutil.copy(current_path, os.path.join( | |
dst, current_path_suffix)) | |
visited_source_paths.add(os.path.realpath(current_path)) | |
if __name__ == '__main__': | |
src = sys.argv[1] | |
dst = sys.argv[2] | |
copy_tree(src, dst) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment