-
Notifications
You must be signed in to change notification settings - Fork 194
/
update-version.py
146 lines (132 loc) · 6.38 KB
/
update-version.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/python3
#
# Version updater
# Copyright (C) 2016 Christopher Gurnee. All rights reserved.
#
# Please refer to readme.md for information about this source code.
# Please refer to license.txt for details about distribution and modification.
#
# Updates various version constants based on HASHCHECK_VERSION_STR in version.h
import sys, os, os.path, re, contextlib, atexit
from warnings import warn
atexit.register(lambda: input('Press Enter to exit ...'))
# When used in a 'with' statement, renames filename to filename.orig and opens filename for
# writing. If an uncaught exception is raised, restores filename.orig, otherwise deletes it.
@contextlib.contextmanager
def overwrite(filename, mode='w', *args, **kwargs):
try:
renamed = filename + '.orig'
os.rename(filename, renamed)
except FileNotFoundError:
renamed = None
try:
file = open(filename, mode, *args, **kwargs)
except:
if renamed:
os.rename(renamed, filename)
raise
try:
yield file
except:
file.close()
os.remove(filename)
if renamed:
os.rename(renamed, filename)
raise
file.close()
if renamed:
os.remove(renamed)
os.chdir(os.path.dirname(__file__))
# Get the "authoritative" version string from HASHCHECK_VERSION_STR in version.h
match = None
with open('version.h', encoding='utf-8') as file:
for line in file:
match = re.match(r'#define\s+HASHCHECK_VERSION_STR\s+"(\d+)\.(\d+)\.(\d+)\.(\d+)((?:-\w+)?)"', line)
if match:
break
if not match:
sys.exit('Valid version not found in version.h')
major = match.group(1)
minor = match.group(2)
patch = match.group(3)
build = match.group(4)
prerelease = match.group(5)
def full_version():
return '.'.join((major, minor, patch, build)) + prerelease
print('v' + full_version())
# Compare the authoritative version with the one in appveyor.yml; since this file
# is updated last, it will be the same iff the authoritative version wasn't changed
match = None
with open('appveyor.yml', encoding='utf-8') as file:
for line in file:
match = re.match(r'version:\s*(\S+)\s*$', line)
if match:
if match.group(1) == full_version():
if input('Version is unchanged, increment build number (Y/n)? ').strip().lower() == 'n':
sys.exit(0)
build = str(int(build) + 1)
print('v' + full_version())
break
# Update the 3 version constants in version.h
found_version_full = 0
found_version_str = 0
found_linker_version = 0
with overwrite('version.h', encoding='utf-8', newline='') as out_file:
with open('version.h.orig', encoding='utf-8', newline='') as in_file:
for line in in_file:
(line, subs) = re.subn(r'^#define\s+HASHCHECK_VERSION_FULL\s+[\d,]+',
'#define HASHCHECK_VERSION_FULL ' + ','.join((major, minor, patch, build)), line)
found_version_full += subs
(line, subs) = re.subn(r'^#define\s+HASHCHECK_VERSION_STR\s+"[\d.\w-]*"',
'#define HASHCHECK_VERSION_STR "' + full_version() + '"', line)
found_version_str += subs
(line, subs) = re.subn(r'^#pragma\s+comment\s*\(\s*linker\s*,\s*"/version:[\d+.]+"\s*\)',
'#pragma comment(linker, "/version:{}.{}")'.format(major, minor), line)
found_linker_version += subs
out_file.write(line)
if found_version_full != 1:
warn('found {} HASHCHECK_VERSION_FULL defines in version.h'.format(found_version_full))
if found_version_str != 1:
warn('found {} HASHCHECK_VERSION_STR defines in version.h'.format(found_version_str))
if found_linker_version != 1:
warn('found {} linker /version lines in version.h'.format(found_linker_version))
# Update the 4 version constants in HashCheck.nsi
found_outfile = 0
found_product_version = 0
found_version_key_product = 0
found_version_key_file = 0
with overwrite(r'installer\HashCheck.nsi', encoding='utf-8', newline='') as out_file:
with open(r'installer\HashCheck.nsi.orig', encoding='utf-8', newline='') as in_file:
for line in in_file:
(line, subs) = re.subn(r'^OutFile\s*"HashCheckSetup-v[\d.\w-]+.exe"',
'OutFile "HashCheckSetup-v' + full_version() + '.exe"', line)
found_outfile += subs
(line, subs) = re.subn(r'^VIProductVersion\s+"[\d.\w-]+"',
'VIProductVersion "' + full_version() + '"', line)
found_product_version += subs
(line, subs) = re.subn(r'^VIAddVersionKey\s+/LANG=\${LANG_ENGLISH}\s+"ProductVersion"\s+"[\d.\w-]+"',
'VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "' + full_version() + '"', line)
found_version_key_product += subs
(line, subs) = re.subn(r'VIAddVersionKey\s+/LANG=\${LANG_ENGLISH}\s+"FileVersion"\s+"[\d.\w-]+"',
'VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "' + full_version() + '"', line)
found_version_key_file += subs
out_file.write(line)
if found_outfile != 1:
warn('found {} OutFile statements in HashCheck.nsi'.format(found_outfile))
if found_product_version != 1:
warn('found {} VIProductVersion\'s in HashCheck.nsi'.format(found_product_version))
if found_version_key_product != 1:
warn('found {} ProductVersion VIAddVersionKeys defines in HashCheck.nsi'.format(found_version_key_product))
if found_version_key_file != 1:
warn('found {} FileVersion VIAddVersionKeys defines in HashCheck.nsi'.format(found_version_key_file))
# Lastly, update the one version line in appveyor
found_version = 0
with overwrite('appveyor.yml', encoding='utf-8', newline='') as out_file:
with open('appveyor.yml.orig', encoding='utf-8', newline='') as in_file:
for line in in_file:
(line, subs) = re.subn(r'^version:\s*\S+', 'version: ' + full_version(), line)
found_version += subs
out_file.write(line)
if found_version != 1:
warn('found {} version lines in appveyor.yml'.format(found_version))
print('Done.')