git2changelog.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #!//usr/bin/env python2.7
  2. from __future__ import print_function
  3. import subprocess
  4. import re
  5. import sys
  6. import datetime
  7. import os
  8. import ConfigParser
  9. try:
  10. long
  11. except NameError:
  12. long = int
  13. distribution="yakkety"
  14. versionTagRE = re.compile("^v([0-9]+((\.[0-9]+)+))(-(.+))?$")
  15. def processVersionTag(tag):
  16. m = versionTagRE.match(tag)
  17. if m:
  18. return (m.group(1), "release" if m.group(4) is None else "beta")
  19. else:
  20. return None
  21. def getCommitVersion(commit):
  22. major=None
  23. minor=None
  24. patch=None
  25. try:
  26. for line in subprocess.check_output(["git", "show",
  27. commit + ":VERSION.cmake"]).splitlines():
  28. m = re.match("set\( MIRALL_VERSION_([A-Z]+) +([0-9]+) *\)", line)
  29. if m is not None:
  30. kind=m.group(1)
  31. version=m.group(2)
  32. if kind=="MAJOR":
  33. major=version
  34. elif kind=="MINOR":
  35. minor=version
  36. elif kind=="PATCH":
  37. patch=version
  38. if major and minor and patch:
  39. return major + "." + minor + "." + patch
  40. else:
  41. return None
  42. except:
  43. return None
  44. def collectEntries(baseCommit, baseVersion, kind, finalBaseVersion, finalRevDate, config):
  45. newVersionCommit = None
  46. newVersionTag = None
  47. newVersionOrigTag = None
  48. if config is not None and config.has_section("versionhack"):
  49. if config.has_option("versionhack", "commit") and \
  50. config.has_option("versionhack", "tag"):
  51. newVersionCommit = config.get("versionhack", "commit")
  52. newVersionTag = config.get("versionhack", "tag")
  53. entries = []
  54. args = ["git", "log",
  55. "--format=%h%x09%an%x09%ae%x09%aD%x09%ad%x09%s",
  56. "--date=unix", "--author-date-order", "--reverse"]
  57. try:
  58. output = subprocess.check_output(args + [baseCommit + ".."])
  59. except:
  60. output = subprocess.check_output(args)
  61. lastVersionTag = None
  62. lastCMAKEVersion = None
  63. for line in output.splitlines():
  64. words = line.split("\t")
  65. (commit, name, email, date, revdate) = words[0:5]
  66. subject = "\t".join(words[5:])
  67. revdate = datetime.datetime.utcfromtimestamp(long(revdate)).strftime("%Y%m%d.%H%M%S")
  68. revdate += "." + commit
  69. kind = "alpha"
  70. if commit==newVersionCommit:
  71. result = processVersionTag(newVersionTag)
  72. if result:
  73. newVersionOrigTag = lastVersionTag
  74. (baseVersion, _kind) = result
  75. version=getCommitVersion(commit)
  76. if version and version!=lastCMAKEVersion:
  77. tag = "v" + version
  78. if tag!=newVersionOrigTag:
  79. result = processVersionTag(tag)
  80. if result:
  81. lastVersionTag = tag
  82. lastCMAKEVersion = version
  83. (baseVersion, _kind) = result
  84. for tag in subprocess.check_output(["git", "tag",
  85. "--points-at",
  86. commit]).splitlines():
  87. if tag!=newVersionOrigTag:
  88. result = processVersionTag(tag)
  89. if result:
  90. lastVersionTag = tag
  91. (baseVersion, kind1) = result
  92. if kind1!=kind and kind!="release":
  93. kind = kind1
  94. entries.append((commit, name, email, date, revdate, subject,
  95. baseVersion, kind))
  96. if entries:
  97. (commit, name, email, date, revdate, subject, baseVersion, kind) = entries[-1]
  98. if finalRevDate is None:
  99. revdate = datetime.datetime.now().strftime("%Y%m%d.%H%M%S")+ "." + commit
  100. else:
  101. revdate = finalRevDate
  102. if finalBaseVersion is not None:
  103. baseVersion = finalBaseVersion
  104. entries[-1] = (commit, name, email, date, revdate, subject, baseVersion, kind)
  105. entries.reverse()
  106. return entries
  107. def genChangeLogEntries(f, entries, distribution):
  108. latestBaseVersion = None
  109. latestRevDate = None
  110. latestKind = None
  111. for (commit, name, email, date, revdate, subject, baseVersion, kind) in entries:
  112. if latestBaseVersion is None:
  113. latestBaseVersion = baseVersion
  114. latestRevDate = revdate
  115. latestKind = kind
  116. upstreamVersion = baseVersion + "-" + revdate
  117. if distribution=="stable":
  118. version = upstreamVersion
  119. else:
  120. version = upstreamVersion + "-1.0~" + distribution + "1"
  121. print("nextcloud-desktop (%s) %s; urgency=medium" % (version, distribution), file=f)
  122. print(file=f)
  123. print(" * " + subject, file=f)
  124. print(file=f)
  125. print(" -- %s <%s> %s" % (name, email, date), file=f)
  126. print(file=f)
  127. return (latestBaseVersion, latestRevDate, latestKind)
  128. if __name__ == "__main__":
  129. scriptdir = os.path.dirname(__file__)
  130. configPath = os.path.join(scriptdir, "git2changelog.cfg")
  131. baseCommit = "f9b1c724d6ab5431e0cd56b7cd834f2dd48cebb1"
  132. baseVersion = "2.4.0"
  133. config = None
  134. if os.path.exists(configPath):
  135. config = ConfigParser.SafeConfigParser()
  136. config.read(configPath)
  137. if config.has_section("base"):
  138. if config.has_option("base", "commit") and \
  139. config.has_option("base", "version"):
  140. baseCommit = config.get("base", "commit")
  141. baseVersion = config.get("base", "version")
  142. distribution = sys.argv[2]
  143. finalRevDate = sys.argv[3] if len(sys.argv)>3 else None
  144. finalBaseVersion = sys.argv[4] if len(sys.argv)>4 else None
  145. entries = collectEntries(baseCommit, baseVersion, "alpha",
  146. finalBaseVersion, finalRevDate, config)
  147. with open(sys.argv[1], "wt") as f:
  148. (baseVersion, revdate, kind) = genChangeLogEntries(f, entries, distribution)
  149. print(baseVersion, revdate, kind)