forked from w3c/csswg-test
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsupportprop.py
executable file
·156 lines (139 loc) · 5.52 KB
/
supportprop.py
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/python
# This file is licensed under CC Zero
import os
from os.path import join
import shutil
import filecmp
# Files to not sync across support/ directories
fileExcludes = ('README')
dirExcludes = ('.svn', '.hg', 'CVS')
# To prevent support files from being propagated into a particular support/
# directory, add a file named LOCK
def propagate(source, dest, errors):
"""Compare each file and copy from source to destination.
Do nothing and flag an error if the destination already exists
but is different. Recurse.
source and dest are both directory paths.
errors is a list of 2-element tuples, the first being a
source filepath and the second a destination filepath,
of file pairs where the destination isdifferent from
"""
# This directory is locked; don't propagate
if os.path.exists(join(dest, 'LOCK')): return
# If the source directory doesn't exist return
if not os.path.exists(source): return
# Get the file and directory lists for source
children = os.listdir(source)
for name in children:
origin = join(source, name)
copy = join(dest, name)
if os.path.isfile(origin):
if name in fileExcludes: continue
# Copy over the file if it needs copying
if not os.path.exists(copy): # file missing
shutil.copy2(origin, copy) # copy it over
elif not filecmp.cmp(origin, copy): # files differ
if not filecmp.cmp(origin, copy, True): # contents equal, stats differ
shutil.copystat(origin, copy) # update stats so they match for next time
else: # contents differ
errors.append((origin, copy))
elif os.path.isdir(origin):
if name in dirExcludes: continue
# Duplicate the directory structure and propagate the subtree
if not os.path.exists(copy):
os.makedirs(copy)
propagate(origin, copy, errors)
if len(children) == 0:
print "Warn: " + source + " is empty.\n"
def waterfall(parentDir, childDir, errors):
"""Copy down support files from parent support to child.
parentDir is the parent of the parent support directory.
childDir is the parent of the current support directory,
that we should copy into.
waterfall recurses into childDir's children."""
assert os.path.exists(join(parentDir, 'support')), join(parentDir, 'support') + " doesn't exist\n"
if os.path.exists(join(childDir, 'support')):
propagate(join(parentDir, 'support'), join(childDir, 'support'), errors)
dirs = os.walk(childDir).next()[1]
for name in dirs:
if name == 'support':
pass
elif name not in dirExcludes:
waterfall(childDir, join(childDir, name), errors)
def outline(source, dest, errors):
"""Copy over directory structure and all files under any support/ directories
source and dest are both directory paths.
errors is a list of 2-element tuples, the first being a
source filepath and the second a destination filepath,
of support file pairs where the destination copy is
different from the source
"""
# Get the directory list for source
dirs = os.walk(source).next()[1]
# Copy directory structure
for name in dirs:
if name in dirExcludes: continue
origin = join(source, name)
copy = join(dest, name)
if not os.path.exists(copy):
os.mkdirs(copy)
if name == 'support':
# Copy support files
propagate(origin, copy, errors)
else:
outline(origin, copy, errors)
def syncSupport(source, dest, errors):
"""For each support directory in dest, propagate the corresponding support
files from source.
source and dest are both directory paths.
errors is a list of 2-element tuples, the first being a
source filepath and the second a destination filepath,
of support file pairs where the destination copy is
different from the source
"""
# Get the directory list for est
dirs = os.walk(dest).next()[1]
# Scan directory structure, building support dirs as necessary
for name in dirs:
if name in dirExcludes: continue
master = join(source, name)
slave = join(dest, name)
if name == 'support':
# Copy support files
propagate(master, slave, errors)
else:
syncSupport(master, slave, errors)
def main():
# Part I: Propagate support files through approved/
errors = []
root, dirs, _ = os.walk('.').next()
if 'approved' in dirs:
root = join(root, 'approved')
suites = os.walk(root).next()[1]
suites = filter(lambda name: name not in dirExcludes, suites)
for suite in suites:
waterfall(root, join(root, suite, 'src'), errors)
else:
print "Failed to find approved/ directory.\n"
exit();
# Part II: Propagate test suite support files into contributors/
if 'contributors' in dirs:
_, contribs, _ = os.walk('contributors').next()
for contributor in contribs:
contribRoot = join('contributors', contributor, 'submitted')
if not os.path.exists(contribRoot): continue # missing submitted folder
dirs = os.walk(contribRoot).next()[1]
for dir in dirs:
# Check if contributor has a top-level directory name matching
# one of our suites; if so, sync any matching support directories
if dir in suites:
suiteRoot = join(root, dir, 'src')
if os.path.exists(suiteRoot):
syncSupport(suiteRoot, join(contribRoot, dir), errors)
else:
print "Failed to find contributors/ directory.\n"
# Print all errors
for error in errors:
print "Mismatch: " + error[0] + " vs " + error [1] + " Copy failed.\n"
if __name__ == "__main__":
main()