blob: 7a961ae1397c6d597b84dfbd47b7d45b2ff0337b [file] [log] [blame]
Hao Nguyen9349e232018-12-14 15:05:48 -08001#!/usr/bin/env python
2
3import datetime
4import re
5import sys
6from xml.dom import minidom
7
8if len(sys.argv) < 2:
9 print """
10[ERROR] Please specify a version.
11
12Example:
13./update_version.py 2.1.3
14"""
15 exit(1)
16
17NEW_VERSION = sys.argv[1]
18NEW_VERSION_INFO = NEW_VERSION.split('.')
19if len(NEW_VERSION_INFO) != 3:
20 print """
21[ERROR] Version must be in the format <MAJOR>.<MINOR>.<MICRO>
22
23Example:
24./update_version.py 2.1.3
25"""
26 exit(1)
27
28
29def Find(elem, tagname):
30 for child in elem.childNodes:
31 if child.nodeName == tagname:
32 return child
33 return None
34
35
36def FindAndClone(elem, tagname):
37 return Find(elem, tagname).cloneNode(True)
38
39
40def ReplaceText(elem, text):
41 elem.firstChild.replaceWholeText(text)
42
43
44def RewriteXml(filename, rewriter, add_xml_prefix=True):
45 document = minidom.parse(filename)
46 rewriter(document)
47 # document.toxml() always prepend the XML version without inserting new line.
48 # We wants to preserve as much of the original formatting as possible, so we
49 # will remove the default XML version and replace it with our custom one when
50 # whever necessary.
51 content = document.toxml().replace('<?xml version="1.0" ?>', '')
52 file_handle = open(filename, 'wb')
53 if add_xml_prefix:
54 file_handle.write('<?xml version="1.0" encoding="UTF-8"?>\n')
55 file_handle.write(content)
Hao Nguyen4b02f652018-12-14 15:10:11 -080056 file_handle.write('\n')
Hao Nguyen9349e232018-12-14 15:05:48 -080057 file_handle.close()
58
59
60def RewriteTextFile(filename, line_rewriter):
61 lines = open(filename, 'r').readlines()
62 updated_lines = []
63 for line in lines:
64 updated_lines.append(line_rewriter(line))
65 if lines == updated_lines:
66 print '%s was not updated. Please double check.' % filename
67 f = open(filename, 'w')
68 f.write(''.join(updated_lines))
69 f.close()
70
71
72def UpdateConfigure():
73 RewriteTextFile('configure.ac',
74 lambda line : re.sub(
75 r'^AC_INIT\(\[Protocol Buffers\],\[.*\],\[protobuf@googlegroups.com\],\[protobuf\]\)$',
76 ('AC_INIT([Protocol Buffers],[%s],[protobuf@googlegroups.com],[protobuf])'
77 % NEW_VERSION),
78 line))
79
80
81def UpdateCpp():
82 cpp_version = '%s00%s00%s' % (
83 NEW_VERSION_INFO[0], NEW_VERSION_INFO[1], NEW_VERSION_INFO[2])
84 def RewriteCpp(line):
85 line = re.sub(
86 r'^#define GOOGLE_PROTOBUF_VERSION .*$',
87 '#define GOOGLE_PROTOBUF_VERSION %s' % cpp_version,
88 line)
Hao Nguyenc70643e2019-01-24 11:42:45 -080089 line = re.sub(
90 r'^#define PROTOBUF_VERSION .*$',
91 '#define PROTOBUF_VERSION %s' % cpp_version,
92 line)
Hao Nguyen9349e232018-12-14 15:05:48 -080093 if NEW_VERSION_INFO[2] == '0':
94 line = re.sub(
95 r'^#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION .*$',
96 '#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION %s' % cpp_version,
97 line)
98 line = re.sub(
Hao Nguyenc70643e2019-01-24 11:42:45 -080099 r'^#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC .*$',
100 '#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC %s' % cpp_version,
101 line)
102 line = re.sub(
Hao Nguyen9349e232018-12-14 15:05:48 -0800103 r'^#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION .*$',
104 '#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION %s' % cpp_version,
105 line)
106 line = re.sub(
107 r'^static const int kMinHeaderVersionForLibrary = .*$',
108 'static const int kMinHeaderVersionForLibrary = %s;' % cpp_version,
109 line)
110 line = re.sub(
111 r'^static const int kMinHeaderVersionForProtoc = .*$',
112 'static const int kMinHeaderVersionForProtoc = %s;' % cpp_version,
113 line)
114 return line
115 RewriteTextFile('src/google/protobuf/stubs/common.h', RewriteCpp)
Hao Nguyenc70643e2019-01-24 11:42:45 -0800116 RewriteTextFile('src/google/protobuf/port_def.inc', RewriteCpp)
Hao Nguyen9349e232018-12-14 15:05:48 -0800117
118
119def UpdateCsharp():
120 RewriteXml('csharp/src/Google.Protobuf/Google.Protobuf.csproj',
121 lambda document : ReplaceText(
122 Find(Find(document.documentElement, 'PropertyGroup'), 'VersionPrefix'),
123 NEW_VERSION),
124 add_xml_prefix=False)
125
126 RewriteXml('csharp/Google.Protobuf.Tools.nuspec',
127 lambda document : ReplaceText(
128 Find(Find(document.documentElement, 'metadata'), 'version'),
129 NEW_VERSION))
130
131
132def UpdateJava():
133 RewriteXml('java/pom.xml',
134 lambda document : ReplaceText(
135 Find(document.documentElement, 'version'), NEW_VERSION))
136
Hao Nguyenc70643e2019-01-24 11:42:45 -0800137 RewriteXml('java/bom/pom.xml',
138 lambda document : ReplaceText(
139 Find(document.documentElement, 'version'), NEW_VERSION))
140
Hao Nguyen9349e232018-12-14 15:05:48 -0800141 RewriteXml('java/core/pom.xml',
142 lambda document : ReplaceText(
143 Find(Find(document.documentElement, 'parent'), 'version'),
144 NEW_VERSION))
145
146 RewriteXml('java/util/pom.xml',
147 lambda document : ReplaceText(
148 Find(Find(document.documentElement, 'parent'), 'version'),
149 NEW_VERSION))
150
151 RewriteXml('protoc-artifacts/pom.xml',
152 lambda document : ReplaceText(
153 Find(document.documentElement, 'version'), NEW_VERSION))
154
155
156def UpdateJavaScript():
157 RewriteTextFile('js/package.json',
158 lambda line : re.sub(
159 r'^ "version": ".*",$',
160 ' "version": "%s",' % NEW_VERSION,
161 line))
162
163
164def UpdateMakefile():
165 protobuf_version_offset = 11
166 expected_major_version = '3'
167 if NEW_VERSION_INFO[0] != expected_major_version:
168 print """[ERROR] Major protobuf version has changed. Please update
169update_version.py to readjust the protobuf_version_offset and
170expected_major_version such that the PROTOBUF_VERSION in src/Makefile.am is
171always increasing.
172 """
173 exit(1)
174
175 protobuf_version_info = '%s:%s:0' % (
176 int(NEW_VERSION_INFO[1]) + protobuf_version_offset, NEW_VERSION_INFO[2])
177 RewriteTextFile('src/Makefile.am',
178 lambda line : re.sub(
179 r'^PROTOBUF_VERSION = .*$',
180 'PROTOBUF_VERSION = %s' % protobuf_version_info,
181 line))
182
183
184def UpdateObjectiveC():
185 RewriteTextFile('Protobuf.podspec',
186 lambda line : re.sub(
187 r"^ s.version = '.*'$",
188 " s.version = '%s'" % NEW_VERSION,
189 line))
190
191
192def UpdatePhp():
193 def Callback(document):
194 def CreateNode(tagname, indent, children):
195 elem = document.createElement(tagname)
196 indent += 1
197 for child in children:
198 elem.appendChild(document.createTextNode('\n' + (' ' * indent)))
199 elem.appendChild(child)
200 indent -= 1
201 elem.appendChild(document.createTextNode('\n' + (' ' * indent)))
202 return elem
203
204 root = document.documentElement
205 version = Find(root, 'version')
206 ReplaceText(Find(version, 'release'), NEW_VERSION)
207 ReplaceText(Find(version, 'api'), NEW_VERSION)
208 now = datetime.datetime.now()
209 ReplaceText(Find(root, 'date'), now.strftime('%Y-%m-%d'))
210 ReplaceText(Find(root, 'time'), now.strftime('%H:%M:%S'))
211 changelog = Find(root, 'changelog')
212 for old_version in changelog.getElementsByTagName('version'):
213 if Find(old_version, 'release').firstChild.nodeValue == NEW_VERSION:
214 print ('[WARNING] Version %s already exists in the change log.'
215 % NEW_VERSION)
216 return
217 changelog.appendChild(document.createTextNode(' '))
218 stability = Find(root, 'stability')
219 release = CreateNode('release', 2, [
220 CreateNode('version', 3, [
221 FindAndClone(version, 'release'),
222 FindAndClone(version, 'api')
223 ]),
224 CreateNode('stability', 3, [
225 FindAndClone(stability, 'release'),
226 FindAndClone(stability, 'api')
227 ]),
228 FindAndClone(root, 'date'),
229 FindAndClone(root, 'time'),
230 FindAndClone(root, 'license'),
231 FindAndClone(root, 'notes')
232 ])
233 changelog.appendChild(release)
234 changelog.appendChild(document.createTextNode('\n '))
235 RewriteXml('php/ext/google/protobuf/package.xml', Callback)
236
237def UpdatePython():
238 RewriteTextFile('python/google/protobuf/__init__.py',
239 lambda line : re.sub(
240 r"^__version__ = '.*'$",
241 "__version__ = '%s'" % NEW_VERSION,
242 line))
243
244def UpdateRuby():
245 RewriteTextFile('ruby/google-protobuf.gemspec',
246 lambda line : re.sub(
247 r'^ s.version = ".*"$',
248 ' s.version = "%s"' % NEW_VERSION,
249 line))
250
251
252UpdateConfigure()
253UpdateCsharp()
254UpdateCpp()
255UpdateJava()
256UpdateJavaScript()
257UpdateMakefile()
258UpdateObjectiveC()
259UpdatePhp()
260UpdatePython()
261UpdateRuby()