bump-version.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #!/usr/bin/env python
  2. import os
  3. import re
  4. import sys
  5. import argparse
  6. from lib.util import execute, get_electron_version, parse_version, scoped_cwd, \
  7. is_nightly, is_beta, is_stable, get_next_nightly, get_next_beta, \
  8. get_next_stable_from_pre, get_next_stable_from_stable, clean_parse_version
  9. SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
  10. def main():
  11. parser = argparse.ArgumentParser(
  12. description='Bump version numbers. Must specify at least one of the three'
  13. +' options:\n'
  14. +' --bump=patch to increment patch version, or\n'
  15. +' --stable to promote current beta to stable, or\n'
  16. +' --version={version} to set version number directly\n'
  17. +'Note that you can use both --bump and --stable '
  18. +'simultaneously.',
  19. formatter_class=argparse.RawTextHelpFormatter
  20. )
  21. parser.add_argument(
  22. '--version',
  23. default=None,
  24. dest='new_version',
  25. help='new version number'
  26. )
  27. parser.add_argument(
  28. '--bump',
  29. action='store',
  30. default=None,
  31. dest='bump',
  32. help='increment [stable | beta | nightly]'
  33. )
  34. parser.add_argument(
  35. '--dry-run',
  36. action='store_true',
  37. default= False,
  38. dest='dry_run',
  39. help='just to check that version number is correct'
  40. )
  41. args = parser.parse_args()
  42. curr_version = get_electron_version()
  43. if args.bump not in ['stable', 'beta', 'nightly']:
  44. raise Exception('bump must be set to either stable, beta or nightly')
  45. if is_nightly(curr_version):
  46. if args.bump == 'nightly':
  47. version = get_next_nightly(curr_version)
  48. elif args.bump == 'beta':
  49. version = get_next_beta(curr_version)
  50. elif args.bump == 'stable':
  51. version = get_next_stable_from_pre(curr_version)
  52. else:
  53. not_reached()
  54. elif is_beta(curr_version):
  55. if args.bump == 'nightly':
  56. version = get_next_nightly(curr_version)
  57. elif args.bump == 'beta':
  58. version = get_next_beta(curr_version)
  59. elif args.bump == 'stable':
  60. version = get_next_stable_from_pre(curr_version)
  61. else:
  62. not_reached()
  63. elif is_stable(curr_version):
  64. if args.bump == 'nightly':
  65. version = get_next_nightly(curr_version)
  66. elif args.bump == 'beta':
  67. version = get_next_beta(curr_version)
  68. elif args.bump == 'stable':
  69. version = get_next_stable_from_stable(curr_version)
  70. else:
  71. not_reached()
  72. else:
  73. raise Exception("Invalid current version: " + curr_version)
  74. if args.new_version == None and args.bump == None and args.stable == False:
  75. parser.print_help()
  76. return 1
  77. versions = clean_parse_version(version)
  78. suffix = ''
  79. if '-' in version:
  80. suffix = '-' + version.split('-')[1]
  81. versions[3] = parse_version(version)[3]
  82. version = version.split('-')[0]
  83. if args.dry_run:
  84. print 'new version number would be: {0}\n'.format(version + suffix)
  85. return 0
  86. with scoped_cwd(SOURCE_ROOT):
  87. update_electron_gyp(version, suffix)
  88. update_win_rc(version, versions)
  89. update_version_h(versions, suffix)
  90. update_info_plist(version)
  91. update_package_json(version, suffix)
  92. tag_version(version, suffix)
  93. print 'Bumped to version: {0}'.format(version + suffix)
  94. def not_reached():
  95. raise Exception('Unreachable code was reached')
  96. def increase_version(versions, index):
  97. for i in range(index + 1, 4):
  98. versions[i] = '0'
  99. versions[index] = str(int(versions[index]) + 1)
  100. return versions
  101. def update_electron_gyp(version, suffix):
  102. pattern = re.compile(" *'version%' *: *'[0-9.]+(-beta[0-9.]*)?(-dev)?"
  103. + "(-nightly[0-9.]*)?'")
  104. with open('electron.gyp', 'r') as f:
  105. lines = f.readlines()
  106. for i in range(0, len(lines)):
  107. if pattern.match(lines[i]):
  108. lines[i] = " 'version%': '{0}',\n".format(version + suffix)
  109. with open('electron.gyp', 'w') as f:
  110. f.write(''.join(lines))
  111. return
  112. def update_win_rc(version, versions):
  113. pattern_fv = re.compile(' FILEVERSION [0-9,]+')
  114. pattern_pv = re.compile(' PRODUCTVERSION [0-9,]+')
  115. pattern_fvs = re.compile(' *VALUE "FileVersion", "[0-9.]+"')
  116. pattern_pvs = re.compile(' *VALUE "ProductVersion", "[0-9.]+"')
  117. win_rc = os.path.join('atom', 'browser', 'resources', 'win', 'atom.rc')
  118. with open(win_rc, 'r') as f:
  119. lines = f.readlines()
  120. versions = [str(v) for v in versions]
  121. for i in range(0, len(lines)):
  122. line = lines[i]
  123. if pattern_fv.match(line):
  124. lines[i] = ' FILEVERSION {0}\r\n'.format(','.join(versions))
  125. elif pattern_pv.match(line):
  126. lines[i] = ' PRODUCTVERSION {0}\r\n'.format(','.join(versions))
  127. elif pattern_fvs.match(line):
  128. lines[i] = ' VALUE "FileVersion", "{0}"\r\n'.format(version)
  129. elif pattern_pvs.match(line):
  130. lines[i] = ' VALUE "ProductVersion", "{0}"\r\n'.format(version)
  131. with open(win_rc, 'w') as f:
  132. f.write(''.join(lines))
  133. def update_version_h(versions, suffix):
  134. version_h = os.path.join('atom', 'common', 'atom_version.h')
  135. with open(version_h, 'r') as f:
  136. lines = f.readlines()
  137. for i in range(0, len(lines)):
  138. line = lines[i]
  139. if 'ATOM_MAJOR_VERSION' in line:
  140. lines[i] = '#define ATOM_MAJOR_VERSION {0}\n'.format(versions[0])
  141. lines[i + 1] = '#define ATOM_MINOR_VERSION {0}\n'.format(versions[1])
  142. lines[i + 2] = '#define ATOM_PATCH_VERSION {0}\n'.format(versions[2])
  143. if (suffix):
  144. lines[i + 3] = '#define ATOM_PRE_RELEASE_VERSION {0}\n'.format(suffix)
  145. else:
  146. lines[i + 3] = '// #define ATOM_PRE_RELEASE_VERSION\n'
  147. with open(version_h, 'w') as f:
  148. f.write(''.join(lines))
  149. return
  150. def update_info_plist(version):
  151. info_plist = os.path.join('atom', 'browser', 'resources', 'mac', 'Info.plist')
  152. with open(info_plist, 'r') as f:
  153. lines = f.readlines()
  154. for i in range(0, len(lines)):
  155. line = lines[i]
  156. if 'CFBundleVersion' in line:
  157. lines[i + 1] = ' <string>{0}</string>\n'.format(version)
  158. if 'CFBundleShortVersionString' in line:
  159. lines[i + 1] = ' <string>{0}</string>\n'.format(version)
  160. with open(info_plist, 'w') as f:
  161. f.write(''.join(lines))
  162. def update_package_json(version, suffix):
  163. package_json = 'package.json'
  164. with open(package_json, 'r') as f:
  165. lines = f.readlines()
  166. for i in range(0, len(lines)):
  167. line = lines[i];
  168. if 'version' in line:
  169. lines[i] = ' "version": "{0}",\n'.format(version + suffix)
  170. break
  171. with open(package_json, 'w') as f:
  172. f.write(''.join(lines))
  173. def tag_version(version, suffix):
  174. execute([
  175. 'git',
  176. 'commit',
  177. '-a',
  178. '-m',
  179. 'Bump v{0}'.format(version + suffix),
  180. '-n'
  181. ])
  182. if __name__ == '__main__':
  183. sys.exit(main())