summaryrefslogtreecommitdiff
path: root/scripts/merge_directories.py
blob: 3f8631bab27e70e46840b3edd19100b1531efbfe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/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()