diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec
index 05779d442e..2ed8c884bc 100644
--- a/csharp/Google.Protobuf.Tools.nuspec
+++ b/csharp/Google.Protobuf.Tools.nuspec
@@ -1,4 +1,4 @@
-
+
Google.Protobuf.Tools
@@ -16,24 +16,24 @@
Protocol Buffers Binary Serialization Format Google proto proto3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
index e65d3969d5..b965f4c1ea 100644
--- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj
+++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
@@ -1,4 +1,4 @@
-
+
C# runtime library for Protocol Buffers - Google's data interchange format.
@@ -30,7 +30,7 @@
-
+
-
+
\ No newline at end of file
diff --git a/java/core/pom.xml b/java/core/pom.xml
index 9dbaff15c5..1ef06a7445 100644
--- a/java/core/pom.xml
+++ b/java/core/pom.xml
@@ -1,7 +1,5 @@
-
+
4.0.0
com.google.protobuf
@@ -156,4 +154,4 @@
-
+
\ No newline at end of file
diff --git a/java/pom.xml b/java/pom.xml
index c46e52bc8b..7cd1e71a69 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -1,7 +1,5 @@
-
+
4.0.0
com.google.protobuf
@@ -218,4 +216,4 @@
util
-
+
\ No newline at end of file
diff --git a/java/util/pom.xml b/java/util/pom.xml
index bcf4f19b05..9e82633495 100644
--- a/java/util/pom.xml
+++ b/java/util/pom.xml
@@ -1,7 +1,5 @@
-
+
4.0.0
com.google.protobuf
@@ -69,10 +67,10 @@
-
-
-
-
+
+
+
+
@@ -128,4 +126,4 @@
-
+
\ No newline at end of file
diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml
index a3bf2752e7..c60ab6e615 100644
--- a/php/ext/google/protobuf/package.xml
+++ b/php/ext/google/protobuf/package.xml
@@ -21,26 +21,24 @@
stable
3-Clause BSD License
-
-GA release.
-
+ GA release.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -54,7 +52,7 @@ GA release.
protobuf
-
+
diff --git a/protoc-artifacts/pom.xml b/protoc-artifacts/pom.xml
index 3f85890823..e7f3365fb0 100644
--- a/protoc-artifacts/pom.xml
+++ b/protoc-artifacts/pom.xml
@@ -1,7 +1,5 @@
-
+
4.0.0
com.google
@@ -98,7 +96,7 @@
subsequent deployments it should be set to what Sonatype has
created, so that all deployments will go to the same repository.
-->
-
+
@@ -133,4 +131,4 @@
-
+
\ No newline at end of file
diff --git a/update_version.py b/update_version.py
new file mode 100755
index 0000000000..148e62b04f
--- /dev/null
+++ b/update_version.py
@@ -0,0 +1,247 @@
+#!/usr/bin/env python
+
+import datetime
+import re
+import sys
+from xml.dom import minidom
+
+if len(sys.argv) < 2:
+ print """
+[ERROR] Please specify a version.
+
+Example:
+./update_version.py 2.1.3
+"""
+ exit(1)
+
+NEW_VERSION = sys.argv[1]
+NEW_VERSION_INFO = NEW_VERSION.split('.')
+if len(NEW_VERSION_INFO) != 3:
+ print """
+[ERROR] Version must be in the format ..
+
+Example:
+./update_version.py 2.1.3
+"""
+ exit(1)
+
+
+def Find(elem, tagname):
+ for child in elem.childNodes:
+ if child.nodeName == tagname:
+ return child
+ return None
+
+
+def FindAndClone(elem, tagname):
+ return Find(elem, tagname).cloneNode(True)
+
+
+def ReplaceText(elem, text):
+ elem.firstChild.replaceWholeText(text)
+
+
+def RewriteXml(filename, rewriter, add_xml_prefix=True):
+ document = minidom.parse(filename)
+ rewriter(document)
+ # document.toxml() always prepend the XML version without inserting new line.
+ # We wants to preserve as much of the original formatting as possible, so we
+ # will remove the default XML version and replace it with our custom one when
+ # whever necessary.
+ content = document.toxml().replace('', '')
+ file_handle = open(filename, 'wb')
+ if add_xml_prefix:
+ file_handle.write('\n')
+ file_handle.write(content)
+ file_handle.close()
+
+
+def RewriteTextFile(filename, line_rewriter):
+ lines = open(filename, 'r').readlines()
+ updated_lines = []
+ for line in lines:
+ updated_lines.append(line_rewriter(line))
+ if lines == updated_lines:
+ print '%s was not updated. Please double check.' % filename
+ f = open(filename, 'w')
+ f.write(''.join(updated_lines))
+ f.close()
+
+
+def UpdateConfigure():
+ RewriteTextFile('configure.ac',
+ lambda line : re.sub(
+ r'^AC_INIT\(\[Protocol Buffers\],\[.*\],\[protobuf@googlegroups.com\],\[protobuf\]\)$',
+ ('AC_INIT([Protocol Buffers],[%s],[protobuf@googlegroups.com],[protobuf])'
+ % NEW_VERSION),
+ line))
+
+
+def UpdateCpp():
+ cpp_version = '%s00%s00%s' % (
+ NEW_VERSION_INFO[0], NEW_VERSION_INFO[1], NEW_VERSION_INFO[2])
+ def RewriteCpp(line):
+ line = re.sub(
+ r'^#define GOOGLE_PROTOBUF_VERSION .*$',
+ '#define GOOGLE_PROTOBUF_VERSION %s' % cpp_version,
+ line)
+ if NEW_VERSION_INFO[2] == '0':
+ line = re.sub(
+ r'^#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION .*$',
+ '#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION %s' % cpp_version,
+ line)
+ line = re.sub(
+ r'^#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION .*$',
+ '#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION %s' % cpp_version,
+ line)
+ line = re.sub(
+ r'^static const int kMinHeaderVersionForLibrary = .*$',
+ 'static const int kMinHeaderVersionForLibrary = %s;' % cpp_version,
+ line)
+ line = re.sub(
+ r'^static const int kMinHeaderVersionForProtoc = .*$',
+ 'static const int kMinHeaderVersionForProtoc = %s;' % cpp_version,
+ line)
+ return line
+ RewriteTextFile('src/google/protobuf/stubs/common.h', RewriteCpp)
+
+
+def UpdateCsharp():
+ RewriteXml('csharp/src/Google.Protobuf/Google.Protobuf.csproj',
+ lambda document : ReplaceText(
+ Find(Find(document.documentElement, 'PropertyGroup'), 'VersionPrefix'),
+ NEW_VERSION),
+ add_xml_prefix=False)
+
+ RewriteXml('csharp/Google.Protobuf.Tools.nuspec',
+ lambda document : ReplaceText(
+ Find(Find(document.documentElement, 'metadata'), 'version'),
+ NEW_VERSION))
+
+
+def UpdateJava():
+ RewriteXml('java/pom.xml',
+ lambda document : ReplaceText(
+ Find(document.documentElement, 'version'), NEW_VERSION))
+
+ RewriteXml('java/core/pom.xml',
+ lambda document : ReplaceText(
+ Find(Find(document.documentElement, 'parent'), 'version'),
+ NEW_VERSION))
+
+ RewriteXml('java/util/pom.xml',
+ lambda document : ReplaceText(
+ Find(Find(document.documentElement, 'parent'), 'version'),
+ NEW_VERSION))
+
+ RewriteXml('protoc-artifacts/pom.xml',
+ lambda document : ReplaceText(
+ Find(document.documentElement, 'version'), NEW_VERSION))
+
+
+def UpdateJavaScript():
+ RewriteTextFile('js/package.json',
+ lambda line : re.sub(
+ r'^ "version": ".*",$',
+ ' "version": "%s",' % NEW_VERSION,
+ line))
+
+
+def UpdateMakefile():
+ protobuf_version_offset = 11
+ expected_major_version = '3'
+ if NEW_VERSION_INFO[0] != expected_major_version:
+ print """[ERROR] Major protobuf version has changed. Please update
+update_version.py to readjust the protobuf_version_offset and
+expected_major_version such that the PROTOBUF_VERSION in src/Makefile.am is
+always increasing.
+ """
+ exit(1)
+
+ protobuf_version_info = '%s:%s:0' % (
+ int(NEW_VERSION_INFO[1]) + protobuf_version_offset, NEW_VERSION_INFO[2])
+ RewriteTextFile('src/Makefile.am',
+ lambda line : re.sub(
+ r'^PROTOBUF_VERSION = .*$',
+ 'PROTOBUF_VERSION = %s' % protobuf_version_info,
+ line))
+
+
+def UpdateObjectiveC():
+ RewriteTextFile('Protobuf.podspec',
+ lambda line : re.sub(
+ r"^ s.version = '.*'$",
+ " s.version = '%s'" % NEW_VERSION,
+ line))
+
+
+def UpdatePhp():
+ def Callback(document):
+ def CreateNode(tagname, indent, children):
+ elem = document.createElement(tagname)
+ indent += 1
+ for child in children:
+ elem.appendChild(document.createTextNode('\n' + (' ' * indent)))
+ elem.appendChild(child)
+ indent -= 1
+ elem.appendChild(document.createTextNode('\n' + (' ' * indent)))
+ return elem
+
+ root = document.documentElement
+ version = Find(root, 'version')
+ ReplaceText(Find(version, 'release'), NEW_VERSION)
+ ReplaceText(Find(version, 'api'), NEW_VERSION)
+ now = datetime.datetime.now()
+ ReplaceText(Find(root, 'date'), now.strftime('%Y-%m-%d'))
+ ReplaceText(Find(root, 'time'), now.strftime('%H:%M:%S'))
+ changelog = Find(root, 'changelog')
+ for old_version in changelog.getElementsByTagName('version'):
+ if Find(old_version, 'release').firstChild.nodeValue == NEW_VERSION:
+ print ('[WARNING] Version %s already exists in the change log.'
+ % NEW_VERSION)
+ return
+ changelog.appendChild(document.createTextNode(' '))
+ stability = Find(root, 'stability')
+ release = CreateNode('release', 2, [
+ CreateNode('version', 3, [
+ FindAndClone(version, 'release'),
+ FindAndClone(version, 'api')
+ ]),
+ CreateNode('stability', 3, [
+ FindAndClone(stability, 'release'),
+ FindAndClone(stability, 'api')
+ ]),
+ FindAndClone(root, 'date'),
+ FindAndClone(root, 'time'),
+ FindAndClone(root, 'license'),
+ FindAndClone(root, 'notes')
+ ])
+ changelog.appendChild(release)
+ changelog.appendChild(document.createTextNode('\n '))
+ RewriteXml('php/ext/google/protobuf/package.xml', Callback)
+
+def UpdatePython():
+ RewriteTextFile('python/google/protobuf/__init__.py',
+ lambda line : re.sub(
+ r"^__version__ = '.*'$",
+ "__version__ = '%s'" % NEW_VERSION,
+ line))
+
+def UpdateRuby():
+ RewriteTextFile('ruby/google-protobuf.gemspec',
+ lambda line : re.sub(
+ r'^ s.version = ".*"$',
+ ' s.version = "%s"' % NEW_VERSION,
+ line))
+
+
+UpdateConfigure()
+UpdateCsharp()
+UpdateCpp()
+UpdateJava()
+UpdateJavaScript()
+UpdateMakefile()
+UpdateObjectiveC()
+UpdatePhp()
+UpdatePython()
+UpdateRuby()
diff --git a/update_version.sh b/update_version.sh
deleted file mode 100755
index 746578b75e..0000000000
--- a/update_version.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/bash
-# Helper script to update version number in various files.
-# Each file has it own string matching syntax to avoid accidentally updating
-# the wrong version number of other dependencies.
-
-if [ "$#" -eq 1 ]; then
- VERSION=$1
- IFS='.' read -ra VERSION_INFO <<< "$VERSION"
-fi
-
-if [ "$#" -ne 1 ] || [ ${#VERSION_INFO[@]} -ne 3 ]; then
- echo "
-Usage: $0 VERSION
-
-Example:
-$0 2.1.3
-"
- exit 1
-fi
-
-update_version() {
- file=$2
- # Replace the version number in the given file.
- sed -ri "$1" $file
- # Verify that the version number is updated successfully.
- if [ $(grep -c $VERSION $file) -eq 0 ]; then
- echo "$file version is not updated successfully. Please verify."
- exit 1
- fi
-}
-
-update_version "s/\[Protocol Buffers\],\[.*\],\[protobuf@googlegroups.com\]/[Protocol Buffers],[$VERSION],[protobuf@googlegroups.com]/g" configure.ac
-update_version "s/^ .*<\/version>/ $VERSION<\/version>/g" java/pom.xml
-update_version "s/^ .*<\/version>/ $VERSION<\/version>/g" java/core/pom.xml
-update_version "s/^ .*<\/version>/ $VERSION<\/version>/g" java/util/pom.xml
-update_version "s/^ .*<\/version>/ $VERSION<\/version>/g" protoc-artifacts/pom.xml
-update_version "s/^ s.version = '.*'/ s.version = '$VERSION'/g" Protobuf.podspec
-update_version "s/^__version__ = '.*'/__version__ = '$VERSION'/g" python/google/protobuf/__init__.py
-update_version "s/^ .*<\/VersionPrefix>/ $VERSION<\/VersionPrefix>/g" csharp/src/Google.Protobuf/Google.Protobuf.csproj
-update_version "s/^ .*<\/version>/ $VERSION<\/version>/g" csharp/Google.Protobuf.Tools.nuspec
-update_version "s/^ \"version\": \".*\",/ \"version\": \"$VERSION\",/g" js/package.json
-update_version "s/^ s.version = \".*\"/ s.version = \"$VERSION\"/g" ruby/google-protobuf.gemspec
-
-# Special handling for C++ file, where version is X.Y.Z is transformed to X00Y00Z
-CPP_VERSION=${VERSION_INFO[0]}00${VERSION_INFO[1]}00${VERSION_INFO[2]}
-sed -ri "s/^#define GOOGLE_PROTOBUF_VERSION .*/#define GOOGLE_PROTOBUF_VERSION $CPP_VERSION/g" src/google/protobuf/stubs/common.h
-
-# Only update these constants if it is a major release.
-if [ ${VERSION_INFO[2]} -eq 0 ]; then
- sed -ri "s/^#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION .*/#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION $CPP_VERSION/g" src/google/protobuf/stubs/common.h
- sed -ri "s/^#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION .*/#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION $CPP_VERSION/g" src/google/protobuf/stubs/common.h
- sed -ri "s/^static const int kMinHeaderVersionForLibrary = .*/static const int kMinHeaderVersionForLibrary = $CPP_VERSION;/g" src/google/protobuf/stubs/common.h
- sed -ri "s/^static const int kMinHeaderVersionForProtoc = .*/static const int kMinHeaderVersionForProtoc = $CPP_VERSION;/g" src/google/protobuf/stubs/common.h
-
- if [ $(grep -c $CPP_VERSION src/google/protobuf/stubs/common.h) -ne 5 ]; then
- echo "src/google/protobuf/stubs/common.h version is not updated successfully. Please verify."
- exit 1
- fi
-else
- if [ $(grep -c $CPP_VERSION src/google/protobuf/stubs/common.h) -ne 1 ]; then
- echo "src/google/protobuf/stubs/common.h version is not updated successfully. Please verify."
- exit 1
- fi
-fi
-
-# Special handling for src/Makefile.am. If version is X.Y.Z, then the
-# version here should be [Y+OFFSET]:Z:0 where OFFSET is some constant
-# such that the version number is always increasing.
-PROTOBUF_VERSION_OFFSET=11
-EXPECTED_MAJOR_VERSION=3
-if [ ${VERSION_INFO[0]} -ne ${EXPECTED_MAJOR_VERSION} ]; then
- echo "Major protobuf version has changed. Please update $0 to readjust
-the PROTOBUF_VERSION_OFFSET and EXPECTED_MAJOR_VERSION such that the
-PROTOBUF_VERSION in src/Makefile.am is always increasing.
- "
- exit 1
-fi
-
-PROTOBUF_VERSION_INFO=$((${VERSION_INFO[1]} + $PROTOBUF_VERSION_OFFSET)):${VERSION_INFO[2]}:0
-sed -ri "s/^PROTOBUF_VERSION = .*/PROTOBUF_VERSION = $PROTOBUF_VERSION_INFO/g" src/Makefile.am
-
-if [ $(grep -c $PROTOBUF_VERSION_INFO src/Makefile.am) -eq 0 ]; then
- echo "src/Makefile.am version is not updated successfully. Please verify."
- exit 1
-fi