update-svn-properties.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #!/usr/bin/env python
  2. import os, os.path, popen2, re, string, sys
  3. def textfile(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 textfile(file)
  34. property_map = {
  35. ".bat" : script,
  36. ".config" : textfile,
  37. ".cs" : textfile,
  38. ".csproj" : textfile,
  39. ".dat" : binary_or_text,
  40. ".dll" : binary,
  41. ".dylib" : binary,
  42. ".example" : textfile,
  43. ".exe" : executable,
  44. ".fxcop" : textfile,
  45. ".ico" : binary,
  46. ".include" : textfile,
  47. ".ini" : textfile,
  48. ".j2c" : binary,
  49. ".jp2" : binary,
  50. ".lsl" : textfile,
  51. ".mdp" : textfile,
  52. ".mds" : textfile,
  53. ".nsi" : textfile,
  54. ".pdb" : binary,
  55. ".php" : script,
  56. ".pidb" : binary,
  57. ".pl" : script,
  58. ".png" : binary,
  59. ".py" : script,
  60. ".rb" : script,
  61. ".resx" : textfile,
  62. ".settings" : textfile,
  63. ".stetic" : textfile,
  64. ".sh" : script,
  65. ".snk" : binary,
  66. ".so" : binary,
  67. ".sql" : textfile,
  68. ".txt" : textfile,
  69. ".userprefs" : textfile,
  70. ".usertasks" : textfile,
  71. ".xml" : textfile,
  72. ".xsd" : textfile
  73. }
  74. def propset(file, property, value):
  75. os.system('svn propset %s "%s" "%s"' % (property, value, file))
  76. def propdel(file, property):
  77. os.system('svn propdel %s "%s"' % (property, file))
  78. def propget(file, property):
  79. output, input, error = popen2.popen3('svn propget %s "%s"' % (property, file))
  80. err = error.read()
  81. if err != "":
  82. output.close()
  83. error.close()
  84. input.close()
  85. return ""
  86. result = output.read()
  87. output.close()
  88. error.close()
  89. input.close()
  90. return result.strip()
  91. def proplist(file):
  92. output, input, error = popen2.popen3('svn proplist "%s"' % file)
  93. err = error.read()
  94. if err != "":
  95. output.close()
  96. error.close()
  97. input.close()
  98. return None
  99. result = output.readlines()
  100. output.close()
  101. error.close()
  102. input.close()
  103. if len(result) > 0 and re.match("^Properties on .*:$", result[0]) is not None:
  104. return [r.strip() for r in result[1:]]
  105. else:
  106. return ""
  107. def update_file(file, properties):
  108. current_props = proplist(file)
  109. if current_props is None:
  110. # svn error occurred -- probably an unversioned file
  111. return
  112. for p in current_props:
  113. if not properties.has_key(p):
  114. propdel(file, p)
  115. for p in properties:
  116. if p not in current_props or propget(file, p) != properties[p]:
  117. propset(file, p, properties[p])
  118. def update(dir):
  119. for f in os.listdir(dir):
  120. fullpath = os.path.join(dir, f)
  121. if os.path.isdir(fullpath):
  122. if not os.path.islink(fullpath):
  123. update(fullpath)
  124. else:
  125. extension = os.path.splitext(fullpath)[1].lower()
  126. if property_map.has_key(extension):
  127. update_file(fullpath, property_map[extension](fullpath))
  128. elif extension != "" and proplist(fullpath) is not None:
  129. print "Warning: No properties defined for %s files (%s)" % (extension, fullpath)
  130. def main(argv = None):
  131. if argv is None:
  132. argv = sys.argv
  133. update(".")
  134. if __name__ == "__main__":
  135. sys.exit(main())