blob: 187e7e6d881e8f0aa88d0d7c37822ab858b233aa [file] [log] [blame]
Hao Nguyen9349e232018-12-14 15:05:48 -08001#!/usr/bin/env python
Hao Nguyene22907f2019-02-20 11:25:39 -08002# Usage: ./update_version.py <MAJOR>.<MINOR>.<MICRO> [<RC version>]
3#
4# Example:
5# ./update_version.py 3.7.1 2
6# => Version will become 3.7.1-rc-2 (beta)
7# ./update_version.py 3.7.1
8# => Version will become 3.7.1 (stable)
Hao Nguyen9349e232018-12-14 15:05:48 -08009
10import datetime
11import re
12import sys
13from xml.dom import minidom
14
Hao Nguyene22907f2019-02-20 11:25:39 -080015if len(sys.argv) < 2 or len(sys.argv) > 3:
Hao Nguyen9349e232018-12-14 15:05:48 -080016 print """
17[ERROR] Please specify a version.
18
Hao Nguyene22907f2019-02-20 11:25:39 -080019./update_version.py <MAJOR>.<MINOR>.<MICRO> [<RC version>]
20
Hao Nguyen9349e232018-12-14 15:05:48 -080021Example:
Hao Nguyene22907f2019-02-20 11:25:39 -080022./update_version.py 3.7.1 2
Hao Nguyen9349e232018-12-14 15:05:48 -080023"""
24 exit(1)
25
26NEW_VERSION = sys.argv[1]
27NEW_VERSION_INFO = NEW_VERSION.split('.')
28if len(NEW_VERSION_INFO) != 3:
29 print """
30[ERROR] Version must be in the format <MAJOR>.<MINOR>.<MICRO>
31
32Example:
Hao Nguyene22907f2019-02-20 11:25:39 -080033./update_version.py 3.7.3
Hao Nguyen9349e232018-12-14 15:05:48 -080034"""
35 exit(1)
36
Hao Nguyene22907f2019-02-20 11:25:39 -080037RC_VERSION = 0
38if len(sys.argv) > 2:
39 RC_VERSION = int(sys.argv[2])
40
Hao Nguyen9349e232018-12-14 15:05:48 -080041
42def Find(elem, tagname):
43 for child in elem.childNodes:
44 if child.nodeName == tagname:
45 return child
46 return None
47
48
49def FindAndClone(elem, tagname):
50 return Find(elem, tagname).cloneNode(True)
51
52
53def ReplaceText(elem, text):
54 elem.firstChild.replaceWholeText(text)
55
56
Hao Nguyene22907f2019-02-20 11:25:39 -080057def GetFullVersion(rc_suffix = '-rc-'):
58 if RC_VERSION == 0:
59 return NEW_VERSION
60 else:
61 return '%s%s%s' % (NEW_VERSION, rc_suffix, RC_VERSION)
62
63
Hao Nguyen9349e232018-12-14 15:05:48 -080064def RewriteXml(filename, rewriter, add_xml_prefix=True):
65 document = minidom.parse(filename)
66 rewriter(document)
67 # document.toxml() always prepend the XML version without inserting new line.
68 # We wants to preserve as much of the original formatting as possible, so we
69 # will remove the default XML version and replace it with our custom one when
70 # whever necessary.
71 content = document.toxml().replace('<?xml version="1.0" ?>', '')
72 file_handle = open(filename, 'wb')
73 if add_xml_prefix:
74 file_handle.write('<?xml version="1.0" encoding="UTF-8"?>\n')
75 file_handle.write(content)
Hao Nguyen4b02f652018-12-14 15:10:11 -080076 file_handle.write('\n')
Hao Nguyen9349e232018-12-14 15:05:48 -080077 file_handle.close()
78
79
80def RewriteTextFile(filename, line_rewriter):
81 lines = open(filename, 'r').readlines()
82 updated_lines = []
83 for line in lines:
84 updated_lines.append(line_rewriter(line))
85 if lines == updated_lines:
86 print '%s was not updated. Please double check.' % filename
87 f = open(filename, 'w')
88 f.write(''.join(updated_lines))
89 f.close()
90
91
92def UpdateConfigure():
93 RewriteTextFile('configure.ac',
94 lambda line : re.sub(
95 r'^AC_INIT\(\[Protocol Buffers\],\[.*\],\[protobuf@googlegroups.com\],\[protobuf\]\)$',
96 ('AC_INIT([Protocol Buffers],[%s],[protobuf@googlegroups.com],[protobuf])'
Hao Nguyene22907f2019-02-20 11:25:39 -080097 % GetFullVersion()),
Hao Nguyen9349e232018-12-14 15:05:48 -080098 line))
99
100
101def UpdateCpp():
102 cpp_version = '%s00%s00%s' % (
103 NEW_VERSION_INFO[0], NEW_VERSION_INFO[1], NEW_VERSION_INFO[2])
Paul Yang6973c3a2019-03-26 09:30:12 -0700104 def RewriteCommon(line):
Hao Nguyen9349e232018-12-14 15:05:48 -0800105 line = re.sub(
106 r'^#define GOOGLE_PROTOBUF_VERSION .*$',
107 '#define GOOGLE_PROTOBUF_VERSION %s' % cpp_version,
108 line)
Hao Nguyenc70643e2019-01-24 11:42:45 -0800109 line = re.sub(
110 r'^#define PROTOBUF_VERSION .*$',
111 '#define PROTOBUF_VERSION %s' % cpp_version,
112 line)
Hao Nguyen9349e232018-12-14 15:05:48 -0800113 if NEW_VERSION_INFO[2] == '0':
114 line = re.sub(
Hao Nguyenc70643e2019-01-24 11:42:45 -0800115 r'^#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC .*$',
116 '#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC %s' % cpp_version,
117 line)
118 line = re.sub(
Hao Nguyen9349e232018-12-14 15:05:48 -0800119 r'^#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION .*$',
120 '#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION %s' % cpp_version,
121 line)
122 line = re.sub(
123 r'^static const int kMinHeaderVersionForLibrary = .*$',
124 'static const int kMinHeaderVersionForLibrary = %s;' % cpp_version,
125 line)
126 line = re.sub(
127 r'^static const int kMinHeaderVersionForProtoc = .*$',
128 'static const int kMinHeaderVersionForProtoc = %s;' % cpp_version,
129 line)
130 return line
Paul Yang6973c3a2019-03-26 09:30:12 -0700131 def RewritePortDef(line):
132 line = re.sub(
133 r'^#define PROTOBUF_VERSION .*$',
134 '#define PROTOBUF_VERSION %s' % cpp_version,
135 line)
136 if NEW_VERSION_INFO[2] == '0':
137 line = re.sub(
138 r'^#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC .*$',
139 '#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC %s' % cpp_version,
140 line)
141 line = re.sub(
142 r'^#define PROTOBUF_MIN_PROTOC_VERSION .*$',
143 '#define PROTOBUF_MIN_PROTOC_VERSION %s' % cpp_version,
144 line)
145 line = re.sub(
146 r'^#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION .*$',
147 '#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION %s' % cpp_version,
148 line)
149 return line
Hao Nguyen5d4e58c2019-04-29 16:52:33 -0700150 def RewritePbH(line):
151 line = re.sub(
152 r'^#if PROTOBUF_VERSION < .*$',
153 '#if PROTOBUF_VERSION < %s' % cpp_version,
154 line)
155 line = re.sub(
156 r'^#if .* < PROTOBUF_MIN_PROTOC_VERSION$',
157 '#if %s < PROTOBUF_MIN_PROTOC_VERSION' % cpp_version,
158 line)
Hao Nguyen39867862019-05-13 17:25:48 -0700159 return line
Hao Nguyen5d4e58c2019-04-29 16:52:33 -0700160
Paul Yang6973c3a2019-03-26 09:30:12 -0700161 RewriteTextFile('src/google/protobuf/stubs/common.h', RewriteCommon)
162 RewriteTextFile('src/google/protobuf/port_def.inc', RewritePortDef)
Hao Nguyen5d4e58c2019-04-29 16:52:33 -0700163 RewriteTextFile('src/google/protobuf/any.pb.h', RewritePbH)
164 RewriteTextFile('src/google/protobuf/api.pb.h', RewritePbH)
165 RewriteTextFile('src/google/protobuf/descriptor.pb.h', RewritePbH)
166 RewriteTextFile('src/google/protobuf/duration.pb.h', RewritePbH)
167 RewriteTextFile('src/google/protobuf/empty.pb.h', RewritePbH)
168 RewriteTextFile('src/google/protobuf/field_mask.pb.h', RewritePbH)
169 RewriteTextFile('src/google/protobuf/source_context.pb.h', RewritePbH)
170 RewriteTextFile('src/google/protobuf/struct.pb.h', RewritePbH)
171 RewriteTextFile('src/google/protobuf/timestamp.pb.h', RewritePbH)
172 RewriteTextFile('src/google/protobuf/wrappers.pb.h', RewritePbH)
173 RewriteTextFile('src/google/protobuf/compiler/plugin.pb.h', RewritePbH)
Hao Nguyen9349e232018-12-14 15:05:48 -0800174
175
176def UpdateCsharp():
177 RewriteXml('csharp/src/Google.Protobuf/Google.Protobuf.csproj',
178 lambda document : ReplaceText(
179 Find(Find(document.documentElement, 'PropertyGroup'), 'VersionPrefix'),
Hao Nguyene22907f2019-02-20 11:25:39 -0800180 GetFullVersion(rc_suffix = '-rc.')),
Hao Nguyen9349e232018-12-14 15:05:48 -0800181 add_xml_prefix=False)
182
183 RewriteXml('csharp/Google.Protobuf.Tools.nuspec',
184 lambda document : ReplaceText(
185 Find(Find(document.documentElement, 'metadata'), 'version'),
Hao Nguyene22907f2019-02-20 11:25:39 -0800186 GetFullVersion(rc_suffix = '-rc.')))
Hao Nguyen9349e232018-12-14 15:05:48 -0800187
188
189def UpdateJava():
190 RewriteXml('java/pom.xml',
191 lambda document : ReplaceText(
Hao Nguyene22907f2019-02-20 11:25:39 -0800192 Find(document.documentElement, 'version'), GetFullVersion()))
Hao Nguyen9349e232018-12-14 15:05:48 -0800193
Hao Nguyenc70643e2019-01-24 11:42:45 -0800194 RewriteXml('java/bom/pom.xml',
195 lambda document : ReplaceText(
Hao Nguyene22907f2019-02-20 11:25:39 -0800196 Find(document.documentElement, 'version'), GetFullVersion()))
Hao Nguyenc70643e2019-01-24 11:42:45 -0800197
Hao Nguyen9349e232018-12-14 15:05:48 -0800198 RewriteXml('java/core/pom.xml',
199 lambda document : ReplaceText(
200 Find(Find(document.documentElement, 'parent'), 'version'),
Hao Nguyene22907f2019-02-20 11:25:39 -0800201 GetFullVersion()))
Hao Nguyen9349e232018-12-14 15:05:48 -0800202
Hao Nguyen13e188f2019-04-23 17:06:40 -0700203 RewriteXml('java/lite/pom.xml',
204 lambda document : ReplaceText(
205 Find(Find(document.documentElement, 'parent'), 'version'),
206 GetFullVersion()))
207
Hao Nguyen9349e232018-12-14 15:05:48 -0800208 RewriteXml('java/util/pom.xml',
209 lambda document : ReplaceText(
210 Find(Find(document.documentElement, 'parent'), 'version'),
Hao Nguyene22907f2019-02-20 11:25:39 -0800211 GetFullVersion()))
Hao Nguyen9349e232018-12-14 15:05:48 -0800212
213 RewriteXml('protoc-artifacts/pom.xml',
214 lambda document : ReplaceText(
Hao Nguyene22907f2019-02-20 11:25:39 -0800215 Find(document.documentElement, 'version'), GetFullVersion()))
Hao Nguyen9349e232018-12-14 15:05:48 -0800216
217
218def UpdateJavaScript():
219 RewriteTextFile('js/package.json',
220 lambda line : re.sub(
221 r'^ "version": ".*",$',
Hao Nguyene22907f2019-02-20 11:25:39 -0800222 ' "version": "%s",' % GetFullVersion(rc_suffix = '-rc.'),
Hao Nguyen9349e232018-12-14 15:05:48 -0800223 line))
224
225
226def UpdateMakefile():
227 protobuf_version_offset = 11
228 expected_major_version = '3'
229 if NEW_VERSION_INFO[0] != expected_major_version:
230 print """[ERROR] Major protobuf version has changed. Please update
231update_version.py to readjust the protobuf_version_offset and
232expected_major_version such that the PROTOBUF_VERSION in src/Makefile.am is
233always increasing.
234 """
235 exit(1)
236
237 protobuf_version_info = '%s:%s:0' % (
238 int(NEW_VERSION_INFO[1]) + protobuf_version_offset, NEW_VERSION_INFO[2])
239 RewriteTextFile('src/Makefile.am',
240 lambda line : re.sub(
241 r'^PROTOBUF_VERSION = .*$',
242 'PROTOBUF_VERSION = %s' % protobuf_version_info,
243 line))
244
245
246def UpdateObjectiveC():
247 RewriteTextFile('Protobuf.podspec',
248 lambda line : re.sub(
249 r"^ s.version = '.*'$",
Hao Nguyene22907f2019-02-20 11:25:39 -0800250 " s.version = '%s'" % GetFullVersion(rc_suffix = '-rc.'),
Hao Nguyen9349e232018-12-14 15:05:48 -0800251 line))
252
253
254def UpdatePhp():
255 def Callback(document):
256 def CreateNode(tagname, indent, children):
257 elem = document.createElement(tagname)
258 indent += 1
259 for child in children:
260 elem.appendChild(document.createTextNode('\n' + (' ' * indent)))
261 elem.appendChild(child)
262 indent -= 1
263 elem.appendChild(document.createTextNode('\n' + (' ' * indent)))
264 return elem
265
266 root = document.documentElement
Paul Yang5d8cd3b2019-02-25 15:13:59 -0800267 now = datetime.datetime.now()
268 ReplaceText(Find(root, 'date'), now.strftime('%Y-%m-%d'))
269 ReplaceText(Find(root, 'time'), now.strftime('%H:%M:%S'))
Hao Nguyen9349e232018-12-14 15:05:48 -0800270 version = Find(root, 'version')
Hao Nguyene22907f2019-02-20 11:25:39 -0800271 ReplaceText(Find(version, 'release'), GetFullVersion(rc_suffix = 'RC'))
Hao Nguyen9349e232018-12-14 15:05:48 -0800272 ReplaceText(Find(version, 'api'), NEW_VERSION)
Hao Nguyene22907f2019-02-20 11:25:39 -0800273 stability = Find(root, 'stability')
Bo Yangb52754b2019-02-22 11:31:48 -0800274 ReplaceText(Find(stability, 'release'),
Hao Nguyene22907f2019-02-20 11:25:39 -0800275 'stable' if RC_VERSION == 0 else 'beta')
Bo Yangb52754b2019-02-22 11:31:48 -0800276 ReplaceText(Find(stability, 'api'), 'stable' if RC_VERSION == 0 else 'beta')
Hao Nguyen9349e232018-12-14 15:05:48 -0800277 changelog = Find(root, 'changelog')
278 for old_version in changelog.getElementsByTagName('version'):
279 if Find(old_version, 'release').firstChild.nodeValue == NEW_VERSION:
280 print ('[WARNING] Version %s already exists in the change log.'
281 % NEW_VERSION)
282 return
283 changelog.appendChild(document.createTextNode(' '))
Hao Nguyen9349e232018-12-14 15:05:48 -0800284 release = CreateNode('release', 2, [
285 CreateNode('version', 3, [
286 FindAndClone(version, 'release'),
287 FindAndClone(version, 'api')
288 ]),
289 CreateNode('stability', 3, [
290 FindAndClone(stability, 'release'),
291 FindAndClone(stability, 'api')
292 ]),
293 FindAndClone(root, 'date'),
294 FindAndClone(root, 'time'),
295 FindAndClone(root, 'license'),
296 FindAndClone(root, 'notes')
297 ])
298 changelog.appendChild(release)
299 changelog.appendChild(document.createTextNode('\n '))
300 RewriteXml('php/ext/google/protobuf/package.xml', Callback)
Paul Yangc7b33922019-02-19 15:54:45 -0800301 RewriteTextFile('php/ext/google/protobuf/protobuf.h',
302 lambda line : re.sub(
303 r'PHP_PROTOBUF_VERSION ".*"$',
304 'PHP_PROTOBUF_VERSION "%s"' % NEW_VERSION,
305 line))
Hao Nguyen9349e232018-12-14 15:05:48 -0800306
Hao Nguyen05f57122019-02-20 11:25:39 -0800307 RewriteTextFile('php/ext/google/protobuf/protobuf.h',
308 lambda line : re.sub(
309 r"^#define PHP_PROTOBUF_VERSION .*$",
310 "#define PHP_PROTOBUF_VERSION \"%s\"" % GetFullVersion(rc_suffix = 'RC'),
311 line))
Hao Nguyen9349e232018-12-14 15:05:48 -0800312
Hao Nguyene22907f2019-02-20 11:25:39 -0800313 RewriteTextFile('php/ext/google/protobuf/protobuf.h',
314 lambda line : re.sub(
315 r"^#define PHP_PROTOBUF_VERSION .*$",
316 "#define PHP_PROTOBUF_VERSION \"%s\"" % GetFullVersion(rc_suffix = 'RC'),
317 line))
318
Hao Nguyen9349e232018-12-14 15:05:48 -0800319def UpdatePython():
320 RewriteTextFile('python/google/protobuf/__init__.py',
321 lambda line : re.sub(
322 r"^__version__ = '.*'$",
Hao Nguyene22907f2019-02-20 11:25:39 -0800323 "__version__ = '%s'" % GetFullVersion(rc_suffix = 'rc'),
Hao Nguyen9349e232018-12-14 15:05:48 -0800324 line))
325
326def UpdateRuby():
327 RewriteTextFile('ruby/google-protobuf.gemspec',
328 lambda line : re.sub(
329 r'^ s.version = ".*"$',
Hao Nguyene22907f2019-02-20 11:25:39 -0800330 ' s.version = "%s"' % GetFullVersion(rc_suffix = '.rc.'),
Hao Nguyen9349e232018-12-14 15:05:48 -0800331 line))
332
333
334UpdateConfigure()
335UpdateCsharp()
336UpdateCpp()
337UpdateJava()
338UpdateJavaScript()
339UpdateMakefile()
340UpdateObjectiveC()
341UpdatePhp()
342UpdatePython()
343UpdateRuby()