update-svn-properties.py 3.8 KB

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