blob: 3a96991816d6f722f07aab04af133a17f6593cd3 [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:
Adam Cozzette17b0fb92021-05-03 16:26:59 -070016 print("""
Hao Nguyen9349e232018-12-14 15:05:48 -080017[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
Adam Cozzette17b0fb92021-05-03 16:26:59 -070023""")
Hao Nguyen9349e232018-12-14 15:05:48 -080024 exit(1)
25
26NEW_VERSION = sys.argv[1]
Jie Luo2a465792019-09-18 13:30:03 -070027NEW_VERSION_INFO = [int(x) for x in NEW_VERSION.split('.')]
Hao Nguyen9349e232018-12-14 15:05:48 -080028if len(NEW_VERSION_INFO) != 3:
Adam Cozzette17b0fb92021-05-03 16:26:59 -070029 print("""
Hao Nguyen9349e232018-12-14 15:05:48 -080030[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
Adam Cozzette17b0fb92021-05-03 16:26:59 -070034""")
Hao Nguyen9349e232018-12-14 15:05:48 -080035 exit(1)
36
Jie Luo2a465792019-09-18 13:30:03 -070037RC_VERSION = -1
Hao Nguyene22907f2019-02-20 11:25:39 -080038if 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-'):
Jie Luo2a465792019-09-18 13:30:03 -070058 if RC_VERSION < 0:
Hao Nguyene22907f2019-02-20 11:25:39 -080059 return NEW_VERSION
60 else:
61 return '%s%s%s' % (NEW_VERSION, rc_suffix, RC_VERSION)
62
63
Joel Johnsona9cf69a2022-02-01 16:27:56 -070064def GetSharedObjectVersion():
65 protobuf_version_offset = 11
66 expected_major_version = 3
67 if NEW_VERSION_INFO[0] != expected_major_version:
68 print("""[ERROR] Major protobuf version has changed. Please update
69update_version.py to readjust the protobuf_version_offset and
70expected_major_version such that the PROTOBUF_VERSION in src/Makefile.am is
71always increasing.
72 """)
73 exit(1)
74 return [NEW_VERSION_INFO[1] + protobuf_version_offset, NEW_VERSION_INFO[2], 0]
75
76
Hao Nguyen9349e232018-12-14 15:05:48 -080077def RewriteXml(filename, rewriter, add_xml_prefix=True):
78 document = minidom.parse(filename)
79 rewriter(document)
80 # document.toxml() always prepend the XML version without inserting new line.
81 # We wants to preserve as much of the original formatting as possible, so we
82 # will remove the default XML version and replace it with our custom one when
83 # whever necessary.
84 content = document.toxml().replace('<?xml version="1.0" ?>', '')
85 file_handle = open(filename, 'wb')
86 if add_xml_prefix:
Adam Cozzette17b0fb92021-05-03 16:26:59 -070087 file_handle.write(b'<?xml version="1.0" encoding="UTF-8"?>\n')
88 file_handle.write(content.encode('utf-8'))
89 file_handle.write(b'\n')
Hao Nguyen9349e232018-12-14 15:05:48 -080090 file_handle.close()
91
92
93def RewriteTextFile(filename, line_rewriter):
94 lines = open(filename, 'r').readlines()
95 updated_lines = []
96 for line in lines:
97 updated_lines.append(line_rewriter(line))
98 if lines == updated_lines:
Adam Cozzette17b0fb92021-05-03 16:26:59 -070099 print('%s was not updated. Please double check.' % filename)
Hao Nguyen9349e232018-12-14 15:05:48 -0800100 f = open(filename, 'w')
101 f.write(''.join(updated_lines))
102 f.close()
103
104
Joel Johnsona9cf69a2022-02-01 16:27:56 -0700105def UpdateCMake():
Arfreverd0c06bc2022-02-23 00:53:14 +0100106 cmake_files = (
107 'cmake/libprotobuf.cmake',
108 'cmake/libprotobuf-lite.cmake',
109 'cmake/libprotoc.cmake'
110 )
111 for cmake_file in cmake_files:
112 RewriteTextFile(cmake_file,
113 lambda line : re.sub(
Adam Cozzetteb44784c2022-02-25 15:30:07 -0800114 r'SOVERSION ([0-9]+)$',
Arfreverd0c06bc2022-02-23 00:53:14 +0100115 'SOVERSION %s' % GetSharedObjectVersion()[0],
116 line))
Joel Johnsona9cf69a2022-02-01 16:27:56 -0700117
118
Hao Nguyen9349e232018-12-14 15:05:48 -0800119def UpdateConfigure():
120 RewriteTextFile('configure.ac',
121 lambda line : re.sub(
122 r'^AC_INIT\(\[Protocol Buffers\],\[.*\],\[protobuf@googlegroups.com\],\[protobuf\]\)$',
123 ('AC_INIT([Protocol Buffers],[%s],[protobuf@googlegroups.com],[protobuf])'
Hao Nguyene22907f2019-02-20 11:25:39 -0800124 % GetFullVersion()),
Hao Nguyen9349e232018-12-14 15:05:48 -0800125 line))
126
127
128def UpdateCpp():
Jie Luo2a465792019-09-18 13:30:03 -0700129 cpp_version = '%d%03d%03d' % (
Hao Nguyen9349e232018-12-14 15:05:48 -0800130 NEW_VERSION_INFO[0], NEW_VERSION_INFO[1], NEW_VERSION_INFO[2])
Adam Cozzette6da79e92020-08-19 11:32:03 -0700131 version_suffix = ''
132 if RC_VERSION != -1:
133 version_suffix = '-rc%s' % RC_VERSION
Paul Yang6973c3a2019-03-26 09:30:12 -0700134 def RewriteCommon(line):
Hao Nguyen9349e232018-12-14 15:05:48 -0800135 line = re.sub(
136 r'^#define GOOGLE_PROTOBUF_VERSION .*$',
137 '#define GOOGLE_PROTOBUF_VERSION %s' % cpp_version,
138 line)
Hao Nguyenc70643e2019-01-24 11:42:45 -0800139 line = re.sub(
140 r'^#define PROTOBUF_VERSION .*$',
141 '#define PROTOBUF_VERSION %s' % cpp_version,
142 line)
Adam Cozzette6da79e92020-08-19 11:32:03 -0700143 line = re.sub(
144 r'^#define GOOGLE_PROTOBUF_VERSION_SUFFIX .*$',
145 '#define GOOGLE_PROTOBUF_VERSION_SUFFIX "%s"' % version_suffix,
146 line)
147 line = re.sub(
148 r'^#define PROTOBUF_VERSION_SUFFIX .*$',
149 '#define PROTOBUF_VERSION_SUFFIX "%s"' % version_suffix,
150 line)
Jie Luo2a465792019-09-18 13:30:03 -0700151 if NEW_VERSION_INFO[2] == 0:
Hao Nguyen9349e232018-12-14 15:05:48 -0800152 line = re.sub(
Hao Nguyenc70643e2019-01-24 11:42:45 -0800153 r'^#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC .*$',
154 '#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC %s' % cpp_version,
155 line)
156 line = re.sub(
Hao Nguyen9349e232018-12-14 15:05:48 -0800157 r'^#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION .*$',
158 '#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION %s' % cpp_version,
159 line)
160 line = re.sub(
161 r'^static const int kMinHeaderVersionForLibrary = .*$',
162 'static const int kMinHeaderVersionForLibrary = %s;' % cpp_version,
163 line)
164 line = re.sub(
165 r'^static const int kMinHeaderVersionForProtoc = .*$',
166 'static const int kMinHeaderVersionForProtoc = %s;' % cpp_version,
167 line)
168 return line
Adam Cozzette6da79e92020-08-19 11:32:03 -0700169
Paul Yang6973c3a2019-03-26 09:30:12 -0700170 def RewritePortDef(line):
171 line = re.sub(
172 r'^#define PROTOBUF_VERSION .*$',
173 '#define PROTOBUF_VERSION %s' % cpp_version,
174 line)
Adam Cozzette6da79e92020-08-19 11:32:03 -0700175 line = re.sub(
176 r'^#define PROTOBUF_VERSION_SUFFIX .*$',
177 '#define PROTOBUF_VERSION_SUFFIX "%s"' % version_suffix,
178 line)
Jie Luo2a465792019-09-18 13:30:03 -0700179 if NEW_VERSION_INFO[2] == 0:
Paul Yang6973c3a2019-03-26 09:30:12 -0700180 line = re.sub(
181 r'^#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC .*$',
182 '#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC %s' % cpp_version,
183 line)
184 line = re.sub(
185 r'^#define PROTOBUF_MIN_PROTOC_VERSION .*$',
186 '#define PROTOBUF_MIN_PROTOC_VERSION %s' % cpp_version,
187 line)
188 line = re.sub(
189 r'^#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION .*$',
190 '#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION %s' % cpp_version,
191 line)
192 return line
Jie Luo43156772019-08-09 13:21:18 -0700193
Jie Luo2a465792019-09-18 13:30:03 -0700194 def RewritePbH(line):
195 line = re.sub(
196 r'^#if PROTOBUF_VERSION < .*$',
197 '#if PROTOBUF_VERSION < %s' % cpp_version,
198 line)
199 line = re.sub(
200 r'^#if .* < PROTOBUF_MIN_PROTOC_VERSION$',
201 '#if %s < PROTOBUF_MIN_PROTOC_VERSION' % cpp_version,
202 line)
203 return line
204
Paul Yang6973c3a2019-03-26 09:30:12 -0700205 RewriteTextFile('src/google/protobuf/stubs/common.h', RewriteCommon)
206 RewriteTextFile('src/google/protobuf/port_def.inc', RewritePortDef)
Jie Luo2a465792019-09-18 13:30:03 -0700207 RewriteTextFile('src/google/protobuf/any.pb.h', RewritePbH)
208 RewriteTextFile('src/google/protobuf/api.pb.h', RewritePbH)
209 RewriteTextFile('src/google/protobuf/descriptor.pb.h', RewritePbH)
210 RewriteTextFile('src/google/protobuf/duration.pb.h', RewritePbH)
211 RewriteTextFile('src/google/protobuf/empty.pb.h', RewritePbH)
212 RewriteTextFile('src/google/protobuf/field_mask.pb.h', RewritePbH)
213 RewriteTextFile('src/google/protobuf/source_context.pb.h', RewritePbH)
214 RewriteTextFile('src/google/protobuf/struct.pb.h', RewritePbH)
215 RewriteTextFile('src/google/protobuf/timestamp.pb.h', RewritePbH)
216 RewriteTextFile('src/google/protobuf/type.pb.h', RewritePbH)
217 RewriteTextFile('src/google/protobuf/wrappers.pb.h', RewritePbH)
218 RewriteTextFile('src/google/protobuf/compiler/plugin.pb.h', RewritePbH)
Hao Nguyen9349e232018-12-14 15:05:48 -0800219
220
221def UpdateCsharp():
222 RewriteXml('csharp/src/Google.Protobuf/Google.Protobuf.csproj',
223 lambda document : ReplaceText(
224 Find(Find(document.documentElement, 'PropertyGroup'), 'VersionPrefix'),
Hao Nguyenfdfe7612019-05-09 06:14:32 -0700225 GetFullVersion(rc_suffix = '-rc')),
Hao Nguyen9349e232018-12-14 15:05:48 -0800226 add_xml_prefix=False)
227
228 RewriteXml('csharp/Google.Protobuf.Tools.nuspec',
229 lambda document : ReplaceText(
230 Find(Find(document.documentElement, 'metadata'), 'version'),
Hao Nguyenfdfe7612019-05-09 06:14:32 -0700231 GetFullVersion(rc_suffix = '-rc')))
Hao Nguyen9349e232018-12-14 15:05:48 -0800232
233
234def UpdateJava():
235 RewriteXml('java/pom.xml',
236 lambda document : ReplaceText(
Hao Nguyene22907f2019-02-20 11:25:39 -0800237 Find(document.documentElement, 'version'), GetFullVersion()))
Hao Nguyen9349e232018-12-14 15:05:48 -0800238
Hao Nguyenc70643e2019-01-24 11:42:45 -0800239 RewriteXml('java/bom/pom.xml',
240 lambda document : ReplaceText(
Hao Nguyene22907f2019-02-20 11:25:39 -0800241 Find(document.documentElement, 'version'), GetFullVersion()))
Hao Nguyenc70643e2019-01-24 11:42:45 -0800242
Hao Nguyen9349e232018-12-14 15:05:48 -0800243 RewriteXml('java/core/pom.xml',
244 lambda document : ReplaceText(
245 Find(Find(document.documentElement, 'parent'), 'version'),
Hao Nguyene22907f2019-02-20 11:25:39 -0800246 GetFullVersion()))
Hao Nguyen9349e232018-12-14 15:05:48 -0800247
Hao Nguyen13e188f2019-04-23 17:06:40 -0700248 RewriteXml('java/lite/pom.xml',
249 lambda document : ReplaceText(
250 Find(Find(document.documentElement, 'parent'), 'version'),
251 GetFullVersion()))
252
Hao Nguyen9349e232018-12-14 15:05:48 -0800253 RewriteXml('java/util/pom.xml',
254 lambda document : ReplaceText(
255 Find(Find(document.documentElement, 'parent'), 'version'),
Hao Nguyene22907f2019-02-20 11:25:39 -0800256 GetFullVersion()))
Hao Nguyen9349e232018-12-14 15:05:48 -0800257
Adam Cozzettef807c022021-05-10 15:31:35 -0700258 RewriteXml('java/kotlin/pom.xml',
259 lambda document : ReplaceText(
260 Find(Find(document.documentElement, 'parent'), 'version'),
261 GetFullVersion()))
262
263 RewriteXml('java/kotlin-lite/pom.xml',
264 lambda document : ReplaceText(
265 Find(Find(document.documentElement, 'parent'), 'version'),
266 GetFullVersion()))
267
Hao Nguyen9349e232018-12-14 15:05:48 -0800268 RewriteXml('protoc-artifacts/pom.xml',
269 lambda document : ReplaceText(
Hao Nguyene22907f2019-02-20 11:25:39 -0800270 Find(document.documentElement, 'version'), GetFullVersion()))
Elliotte Rusty Harolddd3a6482021-10-13 17:34:49 +0000271
272 RewriteTextFile('java/README.md',
273 lambda line : re.sub(
274 r'<version>.*</version>',
275 '<version>%s</version>' % GetFullVersion(),
276 line))
277
278 RewriteTextFile('java/README.md',
279 lambda line : re.sub(
280 r'implementation \'com.google.protobuf:protobuf-java:.*\'',
281 'implementation \'com.google.protobuf:protobuf-java:%s\'' % GetFullVersion(),
282 line))
283
284 RewriteTextFile('java/lite.md',
285 lambda line : re.sub(
286 r'<version>.*</version>',
287 '<version>%s</version>' % GetFullVersion(),
288 line))
Hao Nguyen9349e232018-12-14 15:05:48 -0800289
290
291def UpdateJavaScript():
292 RewriteTextFile('js/package.json',
293 lambda line : re.sub(
294 r'^ "version": ".*",$',
Hao Nguyene22907f2019-02-20 11:25:39 -0800295 ' "version": "%s",' % GetFullVersion(rc_suffix = '-rc.'),
Hao Nguyen9349e232018-12-14 15:05:48 -0800296 line))
297
298
299def UpdateMakefile():
Hao Nguyen9349e232018-12-14 15:05:48 -0800300 RewriteTextFile('src/Makefile.am',
301 lambda line : re.sub(
302 r'^PROTOBUF_VERSION = .*$',
Joel Johnsona9cf69a2022-02-01 16:27:56 -0700303 'PROTOBUF_VERSION = %s' % ":".join(map(str,GetSharedObjectVersion())),
Hao Nguyen9349e232018-12-14 15:05:48 -0800304 line))
305
306
307def UpdateObjectiveC():
308 RewriteTextFile('Protobuf.podspec',
309 lambda line : re.sub(
310 r"^ s.version = '.*'$",
Paul Yang65fed3f2019-05-08 19:15:20 -0700311 " s.version = '%s'" % GetFullVersion(rc_suffix = '-rc'),
Hao Nguyen9349e232018-12-14 15:05:48 -0800312 line))
rmstar2c76c2c2019-07-23 13:51:21 -0700313 RewriteTextFile('Protobuf-C++.podspec',
314 lambda line : re.sub(
315 r"^ s.version = '.*'$",
316 " s.version = '%s'" % GetFullVersion(rc_suffix = '-rc'),
317 line))
Hao Nguyen9349e232018-12-14 15:05:48 -0800318
319
320def UpdatePhp():
321 def Callback(document):
322 def CreateNode(tagname, indent, children):
323 elem = document.createElement(tagname)
324 indent += 1
325 for child in children:
326 elem.appendChild(document.createTextNode('\n' + (' ' * indent)))
327 elem.appendChild(child)
328 indent -= 1
329 elem.appendChild(document.createTextNode('\n' + (' ' * indent)))
330 return elem
331
332 root = document.documentElement
Paul Yang5d8cd3b2019-02-25 15:13:59 -0800333 now = datetime.datetime.now()
334 ReplaceText(Find(root, 'date'), now.strftime('%Y-%m-%d'))
335 ReplaceText(Find(root, 'time'), now.strftime('%H:%M:%S'))
Hao Nguyen9349e232018-12-14 15:05:48 -0800336 version = Find(root, 'version')
Hao Nguyene22907f2019-02-20 11:25:39 -0800337 ReplaceText(Find(version, 'release'), GetFullVersion(rc_suffix = 'RC'))
Hao Nguyen9349e232018-12-14 15:05:48 -0800338 ReplaceText(Find(version, 'api'), NEW_VERSION)
Hao Nguyene22907f2019-02-20 11:25:39 -0800339 stability = Find(root, 'stability')
Bo Yangb52754b2019-02-22 11:31:48 -0800340 ReplaceText(Find(stability, 'release'),
Jie Luo2a465792019-09-18 13:30:03 -0700341 'stable' if RC_VERSION < 0 else 'beta')
342 ReplaceText(Find(stability, 'api'), 'stable' if RC_VERSION < 0 else 'beta')
Hao Nguyen9349e232018-12-14 15:05:48 -0800343 changelog = Find(root, 'changelog')
344 for old_version in changelog.getElementsByTagName('version'):
345 if Find(old_version, 'release').firstChild.nodeValue == NEW_VERSION:
346 print ('[WARNING] Version %s already exists in the change log.'
347 % NEW_VERSION)
348 return
Jie Luo2a465792019-09-18 13:30:03 -0700349 if RC_VERSION != 0:
350 changelog.appendChild(document.createTextNode(' '))
351 release = CreateNode('release', 2, [
352 CreateNode('version', 3, [
353 FindAndClone(version, 'release'),
354 FindAndClone(version, 'api')
355 ]),
356 CreateNode('stability', 3, [
357 FindAndClone(stability, 'release'),
358 FindAndClone(stability, 'api')
359 ]),
360 FindAndClone(root, 'date'),
361 FindAndClone(root, 'time'),
362 FindAndClone(root, 'license'),
Adam Cozzette1b188332020-08-21 11:12:57 -0700363 CreateNode('notes', 3, []),
Jie Luo2a465792019-09-18 13:30:03 -0700364 ])
365 changelog.appendChild(release)
366 changelog.appendChild(document.createTextNode('\n '))
Hao Nguyen9349e232018-12-14 15:05:48 -0800367 RewriteXml('php/ext/google/protobuf/package.xml', Callback)
Paul Yangc7b33922019-02-19 15:54:45 -0800368 RewriteTextFile('php/ext/google/protobuf/protobuf.h',
369 lambda line : re.sub(
Hao Nguyene22907f2019-02-20 11:25:39 -0800370 r"^#define PHP_PROTOBUF_VERSION .*$",
371 "#define PHP_PROTOBUF_VERSION \"%s\"" % GetFullVersion(rc_suffix = 'RC'),
372 line))
373
Hao Nguyen9349e232018-12-14 15:05:48 -0800374def UpdatePython():
375 RewriteTextFile('python/google/protobuf/__init__.py',
376 lambda line : re.sub(
377 r"^__version__ = '.*'$",
Hao Nguyene22907f2019-02-20 11:25:39 -0800378 "__version__ = '%s'" % GetFullVersion(rc_suffix = 'rc'),
Hao Nguyen9349e232018-12-14 15:05:48 -0800379 line))
380
381def UpdateRuby():
Jason Lunn793c66d2021-10-04 17:00:17 +0000382 RewriteXml('ruby/pom.xml',
383 lambda document : ReplaceText(
384 Find(document.documentElement, 'version'), GetFullVersion()))
385 RewriteXml('ruby/pom.xml',
386 lambda document : ReplaceText(
387 Find(Find(Find(document.documentElement, 'dependencies'), 'dependency'), 'version'),
388 GetFullVersion()))
Hao Nguyen9349e232018-12-14 15:05:48 -0800389 RewriteTextFile('ruby/google-protobuf.gemspec',
390 lambda line : re.sub(
391 r'^ s.version = ".*"$',
Hao Nguyene22907f2019-02-20 11:25:39 -0800392 ' s.version = "%s"' % GetFullVersion(rc_suffix = '.rc.'),
Hao Nguyen9349e232018-12-14 15:05:48 -0800393 line))
394
Deanna Garcia66d26f32021-06-25 21:07:31 +0000395def UpdateBazel():
396 RewriteTextFile('protobuf_version.bzl',
397 lambda line : re.sub(
398 r"^PROTOBUF_VERSION = '.*'$",
399 "PROTOBUF_VERSION = '%s'" % GetFullVersion(),
400 line))
401
Hao Nguyen9349e232018-12-14 15:05:48 -0800402
Joel Johnsona9cf69a2022-02-01 16:27:56 -0700403UpdateCMake()
Hao Nguyen9349e232018-12-14 15:05:48 -0800404UpdateConfigure()
405UpdateCsharp()
406UpdateCpp()
407UpdateJava()
408UpdateJavaScript()
409UpdateMakefile()
410UpdateObjectiveC()
411UpdatePhp()
412UpdatePython()
413UpdateRuby()
Deanna Garcia66d26f32021-06-25 21:07:31 +0000414UpdateBazel()