p≡p engine FORK
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
9.4 KiB

  1. import subprocess
  2. import re
  3. import sys
  4. import argparse
  5. parser = argparse.ArgumentParser(description='Automate the RC release process as sanely as possible.')
  6. parser.add_argument('-r','--rev',nargs=1, help="revision number or changeset to tag as next RC")
  7. group = parser.add_mutually_exclusive_group(required=False)
  8. group.add_argument('-v','--version',nargs=4, type=int, help="force this version - bypasses version inference. Format: major minor patch RC")
  9. group.add_argument('--rc', type=int, help="force this RC number on the inferred version")
  10. args = parser.parse_args()
  11. # Note: we could get this from the macros, but since folks seem to be actually upgrading
  12. # the release tag manually correctly and not the macro, let's just check both
  13. cmd = ["hg", "log", "-r", ".", "--template", "\"{latesttag(r're:Release_[0-9]+\.[0-9]+\.[0-9]+-RC[0-9]+')}\""]
  14. result = subprocess.run(cmd, capture_output=True)
  15. release_string = result.stdout.decode("utf-8").replace('"','')
  16. #print(release_string)
  17. changeset = args.rev # can be None :)
  18. major = -1
  19. minor = -1
  20. patch = -1
  21. rc = -1
  22. if args.version:
  23. major = args.version[0]
  24. minor = args.version[1]
  25. patch = args.version[2]
  26. rc = args.version[3]
  27. #print(rc)
  28. if (major < 0) or (minor < 0) or (patch < 0) or (rc < 0):
  29. raise Exception("Version numbers must all be positive values.")
  30. elif args.rc:
  31. rc = args.rc
  32. if (rc < 0):
  33. raise Exception("RC numbers must all be positive values.")
  34. #define PEP_ENGINE_VERSION_MAJOR 2
  35. #define PEP_ENGINE_VERSION_MINOR 1
  36. #define PEP_ENGINE_VERSION_PATCH 0
  37. #define PEP_ENGINE_VERSION_RC 13
  38. # Amateur hour. Biteme.
  39. cmd = ["grep", "-E", "#define PEP_ENGINE_VERSION_[A-Z]+[ \t]+[0-9]+", "src/pEpEngine.h"]
  40. result = subprocess.run(cmd, capture_output=True)
  41. grep_output = result.stdout.decode("utf-8")
  42. #print(grep_output)
  43. if not args.version:
  44. src_nums = []
  45. src_nums = re.findall(r'([0-9]+)', grep_output)
  46. if not src_nums:
  47. raise Exception("Somehow, the source values for the engine versions were not found in src/pEpEngine.h. Aborting.")
  48. if len(src_nums) != 4:
  49. raise Exception("Somehow, we could not extract all version numbers from the header file src/pEpEngine.h. Aborting.")
  50. tag_nums = []
  51. if release_string.startswith("Release_"):
  52. tag_nums = re.findall(r'([0-9]+)', release_string)
  53. # for num in tagnums:
  54. # print (num)
  55. if not tag_nums or len(tag_nums) != 4:
  56. if not tag_nums:
  57. print("Wow... there is no extant release tag. What did you do, wipe the repository?")
  58. else:
  59. print("Somehow, there was an error with the numbering of the tag \"" + release_string + "\"")
  60. print("Do you want to continue? We'll make a tag from the source RC info. (Y/N)[enter]")
  61. a = input().lower()
  62. if not (a.startswith("y") or a.startswith("Y")):
  63. sys.exit()
  64. force = False
  65. if len(tag_nums) == 4 and src_nums:
  66. major_tag = int(tag_nums[0])
  67. major_src = int(src_nums[0])
  68. minor_tag = int(tag_nums[1])
  69. minor_src = int(src_nums[1])
  70. patch_tag = int(tag_nums[2])
  71. patch_src = int(src_nums[2])
  72. rc_tag = int(tag_nums[3])
  73. rc_src = int(src_nums[3])
  74. print("Inferring current/next version info for automatic upgrade:")
  75. print("Tagged (should show current): " + str(major_tag) + "." + str(minor_tag) + "." + str(patch_tag) + "." + str(rc_tag))
  76. print("Source (should show *next* (i.e. this upgrade)): " + str(major_src) + "." + str(minor_src) + "." + str(patch_src) + "." + str(rc_src))
  77. if (major_tag == major_src):
  78. major = major_tag
  79. if (minor_tag == minor_src):
  80. minor = minor_tag
  81. if (patch_tag == patch_src):
  82. patch = patch_tag
  83. # Hoorah, we're just changing the RC number.
  84. if (rc < 0):
  85. if (rc_tag == (rc_src - 1)):
  86. # Best case!
  87. rc = rc_src
  88. elif (rc_tag == rc_src):
  89. print("Someone was naughty and didn't bump the RC number in the src, or you made a mistake you want to fix.")
  90. print("Current tagged version is " + str(major) + "." + str(minor) + "." + str(patch) + " RC" + rc_tag + ".")
  91. print("(I)ncrement,(F)orce same version,(A)bort? [enter]")
  92. a = input().lower()
  93. a = lower(a)
  94. if (a.startswith(i)):
  95. rc = rc_tag + 1
  96. elif (a.startswith(f)):
  97. rc = rc_tag
  98. force = True
  99. else:
  100. print("Aborting...")
  101. sys.exit()
  102. else:
  103. print("RC numbers are messed up. The last tagged version is " + str(rc_tag) + ", while the last source version is " + str(rc_src) + ".")
  104. print("Please enter the RC version you want to use, followed by enter:")
  105. a = input().lower()
  106. rc = int(a) # Will raise value error if not a number. User deserves it, frankly.
  107. #Ok, we now have a value. Good.
  108. # This feels extremely suboptimal, but I'm tired and don't care
  109. if (rc < 0):
  110. if (major < 0):
  111. if (major_src == major_tag + 1) and (minor_src == 0) and (patch_src == 0):
  112. major = major_src
  113. minor = 0
  114. patch = 0
  115. else:
  116. print("Tagged release major version and source versions are too different for automatic deduction. Please do this manually.")
  117. sys.exit()
  118. elif (minor < 0):
  119. if (minor_src == minor_tag + 1) and (patch_src == 0):
  120. minor = minor_src
  121. patch = 0
  122. else:
  123. print("Tagged release major version and source versions are too different for automatic deduction. Please do this manually.")
  124. sys.exit()
  125. elif (patch_src == patch_tag + 1):
  126. patch = patch_src
  127. else:
  128. print("Tagged release major version and source versions are too different for automatic deduction. Please do this manually.")
  129. sys.exit()
  130. # if we got this far, it was a version upgrade.
  131. if (rc_src > 0):
  132. print("We detected a version upgrade, but the source indicates the next RC is RC " + str(rc_src))
  133. print("(K)eep,(R)eset to 0,(A)bort? [enter]")
  134. a = input().lower()
  135. if a.startswith("k"):
  136. rc = rc_src
  137. elif a.startswith("r"):
  138. rc = 0
  139. else:
  140. print("Aborting...")
  141. else:
  142. rc = 0
  143. # Ok, so now, after all that, we should have the right version numbers.
  144. # If there's no changeset to tag, we take the latest local default
  145. if not changeset:
  146. cmd = ["hg", "id", "-i", "-r", "default"]
  147. result = subprocess.run(cmd, capture_output=True)
  148. changeset = result.stdout.decode("utf-8").replace('"','').replace('\n','')
  149. if not changeset:
  150. raise Exception("Unable to determine latest default changeset. Aborting.")
  151. rev_tag = "Release_" + str(major) + "." + str(minor) + "." + str(patch) + "-RC" + str(rc)
  152. print("Preparing to tag changeset " + changeset + " with tag " + rev_tag + ".\n\nProceed? (Y/N) [enter]")
  153. a = input().lower()
  154. if not (a.startswith("y")):
  155. sys.exit()
  156. cmd = ["hg", "tag", "-r", changeset, rev_tag]
  157. subprocess.run(cmd, check=True, capture_output=False)
  158. if not grep_output:
  159. print("Information: Not writing version/RC info to src/pEpEngine.h")
  160. sys.exit()
  161. # If successful, then bump the RC
  162. with open('src/pEpEngine.h', 'r') as file :
  163. filedata = file.read()
  164. grep_strs = grep_output.split("\n")
  165. cmd = ["grep", "-E", "#define PEP_ENGINE_VERSION[ \t]+\"[0-9]+.[0-9]+.[0-9]+\"", "src/pEpEngine.h"]
  166. result = subprocess.run(cmd, capture_output=True)
  167. grep_output = result.stdout.decode("utf-8")
  168. #define PEP_ENGINE_VERSION "2.1.0"
  169. version_str = str(major) + "." + str(minor) + "." + str(patch)
  170. filedata = filedata.replace(grep_output, "#define PEP_ENGINE_VERSION \"" + version_str + "\"\n")
  171. filedata = filedata.replace(grep_strs[0], "#define PEP_ENGINE_VERSION_MAJOR " + str(major))
  172. filedata = filedata.replace(grep_strs[1], "#define PEP_ENGINE_VERSION_MINOR " + str(minor))
  173. filedata = filedata.replace(grep_strs[2], "#define PEP_ENGINE_VERSION_PATCH " + str(patch))
  174. filedata = filedata.replace(grep_strs[3], "#define PEP_ENGINE_VERSION_RC " + str(rc + 1))
  175. # Write the file out again
  176. with open('src/pEpEngine.h', 'w') as file:
  177. file.write(filedata)
  178. comment = "Automatically bumped RC in source for future release. Next RC after this one will be " + version_str + "-RC" + str(rc + 1) + " **if released**."
  179. #print("about to run with this comment:")
  180. print(comment)
  181. cmd = ["hg", "commit", "-m", comment]
  182. subprocess.run(cmd, capture_output=False)
  183. print("New engine release: " + rev_tag + " Changeset: " + changeset)