diff options
Diffstat (limited to 'update-svn-properties.py')
-rwxr-xr-x | update-svn-properties.py | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/update-svn-properties.py b/update-svn-properties.py new file mode 100755 index 0000000..eaf8e9b --- /dev/null +++ b/update-svn-properties.py | |||
@@ -0,0 +1,159 @@ | |||
1 | #!/usr/bin/env python | ||
2 | |||
3 | import os, os.path, popen2, re, string, sys | ||
4 | |||
5 | def textfile(file): | ||
6 | return { | ||
7 | "svn:eol-style" : "native" | ||
8 | } | ||
9 | |||
10 | def script(file): | ||
11 | return { | ||
12 | "svn:eol-style" : "native", | ||
13 | "svn:executable" : "*" | ||
14 | } | ||
15 | |||
16 | def executable(file): | ||
17 | return { | ||
18 | "svn:executable" : "*", | ||
19 | "svn:mime-type" : "application/octet-stream" | ||
20 | } | ||
21 | |||
22 | def binary(file): | ||
23 | return { | ||
24 | "svn:mime-type" : "application/octet-stream" | ||
25 | } | ||
26 | |||
27 | def is_binary(file): | ||
28 | f = open(file) | ||
29 | data = f.read() | ||
30 | f.close() | ||
31 | |||
32 | for c in data: | ||
33 | if c not in string.printable: | ||
34 | return True | ||
35 | return False | ||
36 | |||
37 | def binary_or_text(file): | ||
38 | if is_binary(file): | ||
39 | return binary(file) | ||
40 | else: | ||
41 | return textfile(file) | ||
42 | |||
43 | property_map = { | ||
44 | ".bat" : script, | ||
45 | ".config" : textfile, | ||
46 | ".cs" : textfile, | ||
47 | ".csproj" : textfile, | ||
48 | ".dat" : binary_or_text, | ||
49 | ".dll" : binary, | ||
50 | ".dylib" : binary, | ||
51 | ".example" : textfile, | ||
52 | ".exe" : executable, | ||
53 | ".fxcop" : textfile, | ||
54 | ".ico" : binary, | ||
55 | ".include" : textfile, | ||
56 | ".ini" : textfile, | ||
57 | ".j2c" : binary, | ||
58 | ".jp2" : binary, | ||
59 | ".lsl" : textfile, | ||
60 | ".mdp" : textfile, | ||
61 | ".mds" : textfile, | ||
62 | ".nsi" : textfile, | ||
63 | ".php" : script, | ||
64 | ".pidb" : binary, | ||
65 | ".pl" : script, | ||
66 | ".png" : binary, | ||
67 | ".py" : script, | ||
68 | ".rb" : script, | ||
69 | ".resx" : textfile, | ||
70 | ".settings" : textfile, | ||
71 | ".stetic" : textfile, | ||
72 | ".sh" : script, | ||
73 | ".snk" : binary, | ||
74 | ".so" : binary, | ||
75 | ".sql" : textfile, | ||
76 | ".txt" : textfile, | ||
77 | ".userprefs" : textfile, | ||
78 | ".usertasks" : textfile, | ||
79 | ".xml" : textfile, | ||
80 | ".xsd" : textfile | ||
81 | } | ||
82 | |||
83 | def propset(file, property, value): | ||
84 | os.system('svn propset %s "%s" "%s"' % (property, value, file)) | ||
85 | |||
86 | def propdel(file, property): | ||
87 | os.system('svn propdel %s "%s"' % (property, file)) | ||
88 | |||
89 | def propget(file, property): | ||
90 | output, input, error = popen2.popen3('svn propget %s "%s"' % (property, file)) | ||
91 | |||
92 | err = error.read() | ||
93 | if err != "": | ||
94 | output.close() | ||
95 | error.close() | ||
96 | input.close() | ||
97 | return "" | ||
98 | |||
99 | result = output.read() | ||
100 | output.close() | ||
101 | error.close() | ||
102 | input.close() | ||
103 | return result.strip() | ||
104 | |||
105 | def proplist(file): | ||
106 | output, input, error = popen2.popen3('svn proplist "%s"' % file) | ||
107 | |||
108 | err = error.read() | ||
109 | if err != "": | ||
110 | output.close() | ||
111 | error.close() | ||
112 | input.close() | ||
113 | return None | ||
114 | |||
115 | result = output.readlines() | ||
116 | output.close() | ||
117 | error.close() | ||
118 | input.close() | ||
119 | if len(result) > 0 and re.match("^Properties on .*:$", result[0]) is not None: | ||
120 | return [r.strip() for r in result[1:]] | ||
121 | else: | ||
122 | return "" | ||
123 | |||
124 | def update_file(file, properties): | ||
125 | current_props = proplist(file) | ||
126 | |||
127 | if current_props is None: | ||
128 | # svn error occurred -- probably an unversioned file | ||
129 | return | ||
130 | |||
131 | for p in current_props: | ||
132 | if not properties.has_key(p): | ||
133 | propdel(file, p) | ||
134 | |||
135 | for p in properties: | ||
136 | if p not in current_props or propget(file, p) != properties[p]: | ||
137 | propset(file, p, properties[p]) | ||
138 | |||
139 | def update(dir): | ||
140 | for f in os.listdir(dir): | ||
141 | fullpath = os.path.join(dir, f) | ||
142 | if os.path.isdir(fullpath): | ||
143 | if not os.path.islink(fullpath): | ||
144 | update(fullpath) | ||
145 | else: | ||
146 | extension = os.path.splitext(fullpath)[1].lower() | ||
147 | if property_map.has_key(extension): | ||
148 | update_file(fullpath, property_map[extension](fullpath)) | ||
149 | elif extension != "" and proplist(fullpath) is not None: | ||
150 | print "Warning: No properties defined for %s files (%s)" % (extension, fullpath) | ||
151 | |||
152 | def main(argv = None): | ||
153 | if argv is None: | ||
154 | argv = sys.argv | ||
155 | |||
156 | update(".") | ||
157 | |||
158 | if __name__ == "__main__": | ||
159 | sys.exit(main()) | ||