]> git.donarmstrong.com Git - lilypond.git/blob - buildscripts/mirrortree.py
Merge branch 'master' of git://git.sv.gnu.org/lilypond
[lilypond.git] / buildscripts / mirrortree.py
1 #!@PYTHON@
2
3 import re
4 import os
5
6 def new_link_path (link, dir, r):
7     l = link.split ('/')
8     d = dir.split ('/')
9     i = 0
10     while i < len(d) and i < len(l) and l[i] == '..':
11         if r.match (d[i]):
12             del l[i]
13         else:
14             i += 1
15     return '/'.join ([x for x in l if not r.match (x)])
16
17 def hardlink_tree (input_roots = [],
18                    process_dirs = '.*',
19                    strip_dir_names = '',
20                    exclude_dirs = '',
21                    process_files = '.*',
22                    find_files = '',
23                    exclude_files = '',
24                    target_pattern = '',
25                    targets = ['.']):
26     """Mirror trees for different targets by hardlinking files.
27
28     Arguments:
29      input_roots=DIRLIST      use DIRLIST as input tree roots list
30      process_dir=PATTERN      only process files in directories named PATTERN
31      strip_dir_names=PATTERN  strip directories names matching PATTERN 
32                                  (write their content to parent)
33      exclude_dir=PATTERN      don't recurse into directories named PATTERN
34      process_files=PATTERN    filters files which are hardlinked
35      find_files=PATTERN       find files named PATTERN. The files list will be returned.
36      exclude_files=PATTERN    exclude files named PATTERN
37      target_pattern=STRING    use STRING as target root directory name pattern
38      targets=DIRLIST          mkdir each directory in DIRLIST and mirrors the tree into each
39     """
40     process_files_re = re.compile (process_files)
41     find_files_re = re.compile (find_files)
42     exclude_dirs_re = re.compile (exclude_dirs)
43     exclude_files_re = re.compile (exclude_files)
44     process_dirs_re = re.compile (process_dirs)
45     strip_dir_names_re = re.compile (strip_dir_names)
46     do_strip_dir_names_re = re.compile ('/(?:' + strip_dir_names + ')')
47
48     found_files = []
49
50     if not '%s' in target_pattern:
51         target_pattern += '%s'
52     target_dirs = [target_pattern % s for s in targets]
53
54     map (os.mkdir, target_dirs)
55
56     for d in input_roots:
57         for in_dir, dirs, files in os.walk(d):
58             out_dir = strip_dir_names_re.sub ('', in_dir)
59             i = 0
60             while i < len(dirs):
61                 if exclude_dirs_re.search (dirs[i]):
62                     del dirs[i]
63                 else:
64                     if os.path.islink (os.path.join (in_dir, dirs[i])):
65                         files.append (dirs[i])
66                     i += 1
67             if not strip_dir_names_re.match (os.path.basename (in_dir)):
68                 for t in target_dirs:
69                     p = os.path.join (t, out_dir)
70                     if not os.path.isdir (p):
71                         os.mkdir (p)
72             if not process_dirs_re.search (in_dir):
73                 continue
74             for f in files:
75                 if exclude_files_re.match (f):
76                     continue
77                 in_file = os.path.join (in_dir, f)
78                 if find_files_re.match (f):
79                     found_files.append (in_file)
80                 if os.path.islink (in_file): # all symlinks are assumed to be relative and to point to files in the input trees
81                     link_path = new_link_path (os.path.normpath (os.readlink (in_file)), in_dir, do_strip_dir_names_re)
82                     for t in target_dirs:
83                         os.symlink (link_path, os.path.join (t, out_dir, f))
84                 elif process_files_re.match (f):
85                     for t in target_dirs:
86                         os.link (in_file, os.path.join (t, out_dir, f))
87     return found_files