File: okapi_dir.py

package info (click to toggle)
cde 0.1%2Bgit9-g551e54d-1.1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 10,340 kB
  • ctags: 10,812
  • sloc: ansic: 75,881; sh: 4,282; python: 1,006; perl: 438; makefile: 297; lisp: 44; java: 5
file content (99 lines) | stat: -rw-r--r-- 2,871 bytes parent folder | download | duplicates (6)
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# Deep copy an entire directory argv[1] into another directory argv[2]
# ---
#
# Use okapi to copy over all sub-directories and symlinks, and to make
# sure that all symlinks are properly munged to point to relative paths
# within the package.  (Note that rsync does NOT munge symlinks or
# faithfully re-create the original directory structure in the presence
# of symlinks to directories.)
#
# by Philip Guo

'''
A brief attempt to explain how okapi_dir.py should be used:

argv[1] should be an ABSOLUTE PATH to a directory on your system
argv[2] can be an absolute or relative path to a directory

okapi_dir.py copies the entire directory tree in argv[1] into argv[2],
preserving all sub-directory and symlink structure.

For example, let's say you run:

  mkdir /tmp/A/

Then populate /tmp/A/ with some contents so that it looks like this:

  /tmp/A
  /tmp/A/A-subdir
  /tmp/A/A-subdir/one.txt
  /tmp/A/A-subdir/two.txt
  /tmp/A/A-subdir/A-subsubdir
  /tmp/A/A-subdir/A-subsubdir/three.txt

Now you run:

  mkdir B/

In order to copy the entirety of /tmp/A into B/, you run:

  python CDE/scripts/okapi_dir.py /tmp/A/ B/

and now the contents of B will look like:

  B/tmp/A
  B/tmp/A/A-subdir
  B/tmp/A/A-subdir/one.txt
  B/tmp/A/A-subdir/two.txt
  B/tmp/A/A-subdir/A-subsubdir
  B/tmp/A/A-subdir/A-subsubdir/three.txt

'''

import os, sys, subprocess

def run_cmd_print_stderr(args):
  (cmd_stdout, cmd_stderr) = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
  cmd_stderr = cmd_stderr.strip()
  if cmd_stderr:
    print cmd_stderr


script_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
OKAPI_BIN = os.path.normpath(os.path.join(script_dir, "../okapi"))
assert os.path.isfile(OKAPI_BIN)


def okapi_dir(basedir, dst_root_dir):
  assert os.path.isdir(basedir)

  for (d, subdirs, files) in os.walk(basedir):
    # first copy over the directory so that it exists even if it's empty:
    run_cmd_print_stderr([OKAPI_BIN, d, '', dst_root_dir])

    # now copy over all the files
    for f in files:
      p = os.path.join(d, f)
      run_cmd_print_stderr([OKAPI_BIN, p, '', dst_root_dir])

    # if any subdirs are symlinks, then copy them over as well to
    # preserve the original directory/symlink structure:
    for sd in subdirs:
      p = os.path.join(d, sd)
      if os.path.islink(p):
        run_cmd_print_stderr([OKAPI_BIN, p, '', dst_root_dir])
        # follow the symlink
        dir_symlink_target = os.path.realpath(p)

        # only recurse if dir_symlink_target is OUTSIDE of basedir
        # to (hopefully) prevent infinite loops
        base_realpath = os.path.realpath(basedir)
        if not dir_symlink_target.startswith(base_realpath):
          okapi_dir(dir_symlink_target, dst_root_dir)


if __name__ == "__main__":
  dst = sys.argv[2]
  assert os.path.isdir(dst)
  okapi_dir(sys.argv[1], dst)