61 lines
2 KiB
Python
61 lines
2 KiB
Python
|
#!/usr/bin/env python3
|
||
|
import argparse
|
||
|
import os
|
||
|
import shutil
|
||
|
import sys
|
||
|
|
||
|
def main():
|
||
|
parser = argparse.ArgumentParser(
|
||
|
description="Given a list of directories, this script will copy the contents of all of "
|
||
|
"them into the first directory, erroring out if any duplicate files are found."
|
||
|
)
|
||
|
parser.add_argument(
|
||
|
"--ignore-duplicates",
|
||
|
action="store_true",
|
||
|
help="Don't error out on duplicate files, just skip them. The file from the earliest "
|
||
|
"directory listed on the command line will be the winner."
|
||
|
)
|
||
|
parser.add_argument(
|
||
|
"--file-list",
|
||
|
help="Path to a text file containing paths relative to in_dir. Only these paths will be "
|
||
|
"copied out of in_dir."
|
||
|
)
|
||
|
parser.add_argument("out_dir")
|
||
|
parser.add_argument("in_dir")
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
if not os.path.isdir(args.out_dir):
|
||
|
sys.exit(f"error: {args.out_dir} must be a directory")
|
||
|
if not os.path.isdir(args.in_dir):
|
||
|
sys.exit(f"error: {args.in_dir} must be a directory")
|
||
|
|
||
|
file_list = None
|
||
|
if args.file_list:
|
||
|
with open(file_list_file, "r") as f:
|
||
|
file_list = f.read().strip().splitlines()
|
||
|
|
||
|
in_dir = args.in_dir
|
||
|
for root, dirs, files in os.walk(in_dir):
|
||
|
rel_root = os.path.relpath(root, in_dir)
|
||
|
dst_root = os.path.join(args.out_dir, rel_root)
|
||
|
made_parent_dirs = False
|
||
|
for f in files:
|
||
|
src = os.path.join(root, f)
|
||
|
dst = os.path.join(dst_root, f)
|
||
|
p = os.path.normpath(os.path.join(rel_root, f))
|
||
|
if file_list is not None and p not in file_list:
|
||
|
continue
|
||
|
if os.path.lexists(dst):
|
||
|
if args.ignore_duplicates:
|
||
|
continue
|
||
|
sys.exit(f"error: {p} exists in both {args.out_dir} and {in_dir}")
|
||
|
|
||
|
if not made_parent_dirs:
|
||
|
os.makedirs(dst_root, exist_ok=True)
|
||
|
made_parent_dirs = True
|
||
|
|
||
|
shutil.copy2(src, dst, follow_symlinks=False)
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|