update-svn-properties.py 3.9 KB

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