blob: 4ed7c5174af427434810bb54789acfa395fb0b9a [file] [log] [blame]
James E. King IIIecebd772018-12-28 08:50:58 -05001#!/usr/bin/env bash
2#
3# Licensed to the Apache Software Foundation (ASF) under one
4# or more contributor license agreements. See the NOTICE file
5# distributed with this work for additional information
6# regarding copyright ownership. The ASF licenses this file
7# to you under the Apache License, Version 2.0 (the
8# "License"); you may not use this file except in compliance
9# with the License. You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing,
14# software distributed under the License is distributed on an
15# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16# KIND, either express or implied. See the License for the
17# specific language governing permissions and limitations
18# under the License.
19#
20
21#
22# The veralign script sets the appropriate versions in all of
23# the package configuration files for all of the supported
24# languages. It is used to prepare a release or move master
25# forward to the next anticipated version.
26#
27# USAGE
28# -----------------------------------------------------------
29# usage: veralign.sh <oldVersion> <newVersion>
30#
31# EXAMPLE
32# -----------------------------------------------------------
33# $ ./veralign.sh 0.12.0 1.0.0
34# $ ./veralign.sh 1.0.0 1.1.0
35#
36# IMPORTANT USAGE NOTE
37# -----------------------------------------------------------
38# Define the environment variable DRYRUN to have the script
39# print out all matches to the oldVersion hilighted so that
40# you can verify it will change the right things.
41#
42
43declare -A FILES
44
45# These files require a manual touch:
James E. King IIIe824efc2019-01-07 16:50:54 -050046FILES[CHANGES.md]=manual
James E. King IIIecebd772018-12-28 08:50:58 -050047FILES[debian/changelog]=manual
48FILES[doap.rdf]=manual
49
50# These files can be updated automatically:
51FILES[ApacheThrift.nuspec]=simpleReplace
James E. King IIIc9ac8d22019-01-07 16:46:45 -050052FILES[CMakeLists.txt]=simpleReplace
James E. King IIIecebd772018-12-28 08:50:58 -050053FILES[Thrift-swift3.podspec]=simpleReplace
54FILES[Thrift.podspec]=simpleReplace
55FILES[appveyor.yml]=simpleReplace
56FILES[bower.json]=jsonReplace
James E. King IIIecebd772018-12-28 08:50:58 -050057FILES[configure.ac]=configureReplace
58FILES[contrib/thrift.spec]=simpleReplace
59FILES[lib/cocoa/src/Thrift.h]=simpleReplace
60FILES[lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs]=simpleReplace
61FILES[lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj]=simpleReplace
62FILES[lib/csharp/src/Properties/AssemblyInfo.cs]=simpleReplace
63FILES[lib/csharp/src/Thrift.csproj]=simpleReplace
64FILES[lib/csharp/test/Multiplex/Client/MultiplexClient.csproj]=simpleReplace
65FILES[lib/csharp/test/Multiplex/Client/Properties/AssemblyInfo.cs]=simpleReplace
66FILES[lib/csharp/test/Multiplex/Server/MultiplexServer.csproj]=simpleReplace
67FILES[lib/csharp/test/Multiplex/Server/Properties/AssemblyInfo.cs]=simpleReplace
68FILES[lib/csharp/test/ThriftMVCTest/Properties/AssemblyInfo.cs]=simpleReplace
69FILES[lib/d/src/thrift/base.d]=simpleReplace
70FILES[lib/dart/pubspec.yaml]=pubspecReplace
71FILES[lib/delphi/src/Thrift.pas]=simpleReplace
72FILES[lib/erl/src/thrift.app.src]=simpleReplace
73FILES[lib/haxe/haxelib.json]=simpleReplace
74FILES[lib/hs/thrift.cabal]=simpleReplace
75FILES[lib/java/gradle.properties]=simpleReplace
76FILES[lib/js/package.json]=jsonReplace
77FILES[lib/js/src/thrift.js]=simpleReplace
78FILES[lib/lua/Thrift.lua]=simpleReplace
79FILES[lib/netcore/Thrift/Properties/AssemblyInfo.cs]=simpleReplace
80FILES[lib/netcore/Thrift/Transports/Client/THttpClientTransport.cs]=simpleReplace
81FILES[lib/ocaml/_oasis]=simpleReplace
82FILES[lib/perl/lib/Thrift.pm]=simpleReplace
83FILES[lib/py/setup.py]=simpleReplace
84FILES[lib/rb/thrift.gemspec]=simpleReplace
85FILES[lib/rs/Cargo.toml]=simpleReplace
86FILES[lib/st/package.xml]=simpleReplace
James E. King IIId7c11ad2019-01-11 19:19:44 -050087FILES[lib/swift/Sources/Thrift.swift]=simpleReplace
James E. King III17355422019-01-11 23:06:08 -050088FILES[lib/swift/Tests/ThriftTests/ThriftTests.swift]=simpleReplace
James E. King IIIecebd772018-12-28 08:50:58 -050089FILES[package.json]=jsonReplace
90FILES[sonar-project.properties]=simpleReplace
91FILES[test/csharp/Properties/AssemblyInfo.cs]=simpleReplace
92FILES[test/csharp/ThriftTest.csproj]=simpleReplace
93FILES[test/dart/test_client/pubspec.yaml]=pubspecReplace
94FILES[test/erl/src/thrift_test.app.src]=simpleReplace
95FILES[tutorial/csharp/CsharpClient/Properties/AssemblyInfo.cs]=simpleReplace
96FILES[tutorial/csharp/CsharpServer/Properties/AssemblyInfo.cs]=simpleReplace
97FILES[tutorial/dart/client/pubspec.yaml]=pubspecReplace
98FILES[tutorial/dart/console_client/pubspec.yaml]=pubspecReplace
99FILES[tutorial/dart/server/pubspec.yaml]=pubspecReplace
100FILES[tutorial/delphi/DelphiClient/DelphiClient.dproj]=simpleReplace
101FILES[tutorial/delphi/DelphiServer/DelphiServer.dproj]=simpleReplace
102FILES[tutorial/hs/ThriftTutorial.cabal]=simpleReplace
103FILES[tutorial/ocaml/_oasis]=simpleReplace
104
James E. King IIIc9ac8d22019-01-07 16:46:45 -0500105if [ ! -f "CHANGES.md" ]; then
James E. King IIIecebd772018-12-28 08:50:58 -0500106 >&2 echo "error: run veralign.sh while in the thrift root directory"
107 exit 1
108fi
109
110if [ $# -ne 2 ]; then
111 >&2 echo "usage: veralign.sh <oldVersion> <newVersion>"
112 exit 1
113fi
114
115jq --version 1>/dev/null 2>/dev/null
116if [ $? -ne 0 ]; then
117 >&2 echo "error: the 'jq' package is not installed"
118 exit 1
119fi
120
121#
122# validateVersion: check that a version matches the major.minor.patch
123# format which is the lowest common denominator supported by all
124# project systems.
125# \param $1 the version
126# \returns 0 if the version is compliant
127#
128function validateVersion
129{
130 local result
131 local valid
132 valid=$(echo "$1" | sed '/^[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+$/!{q22}')
133 result=$?
134 if [ $result -eq 22 ]; then
135 >&2 echo "error: version '$1' does not conform to the required major.minor.patch format"
136 return ${result}
137 fi
138}
139
140OLDVERSION=$1
141NEWVERSION=$2
142validateVersion "${OLDVERSION}" || exit $?
143validateVersion "${NEWVERSION}" || exit $?
144
145#
146# escapeVersion: escape the version for use as a sed search
147# \param $1 the version to escape
148# \output the escaped string
149# \returns 0
150# \example VERSEARCH=$(escapeVersion "[1.0.0]"); echo $VERSEARCH; => "\[1\.0\.0\]"
151#
152function escapeVersion
153{
154 echo "$(echo $1 | sed 's/\./\\./g' | sed 's/\[/\\\[/g' | sed 's/\]/\\\]/g')"
155}
156
157# Set up verbose hilighting if running interactive
158if [ "$(tput colors)" -ne 0 ]; then
159 reverse=$(tput rev)
160 red=$(tput setaf 1)
161 green=$(tput setaf 2)
162 yellow=$(tput setaf 3)
163 normal=$(tput sgr0)
164fi
165
166declare -A MANUAL
167
168#
169# manual: note that update of said file is manual
170# \param $1 filename to do replacements on
171# \returns 0
172#
173function manual
174{
175 MANUAL["$1"]=""
176 return 0
177}
178
179#
180# configureReplace: replace the AC_INIT field in configure.ac
181# \param $1 filename to do replacements on
182# \returns 0 on success
183#
184
185function configureReplace
186{
187 replace "$1" "[thrift], [${OLDVERSION}]" "[thrift], [${NEWVERSION}]"
188}
189
190#
191# jsonReplace: replace a specific version field in a JSON file
192# must be a top level "version" field in the json structure
193# \param $1 filename to do replacements on
194# \returns 0 on success
195#
196
197function jsonReplace
198{
199 local result
200 local output
201 if [ ! -z "$DRYRUN" ]; then
202 output=$(jq -e ".version" "$1")
203 else
204 output=$(jq -e ".version = \"${NEWVERSION}\"" "$1" > tmp.$$.json && mv tmp.$$.json "$1")
205 fi
206 result=$?
207 if [ $? -ne 0 ]; then
208 printf "%-60s | %5d | ${red}ERROR${normal}: version tag not found" "$1" "$count"
209 echo
210 return 1
211 elif [ ! -z "$DRYRUN" ]; then
212 output=${output%\"}
213 output=${output#\"}
214 printf "%-60s | %5d | MATCHES: version: \"${reverse}${green}${output}${normal}\"" "$1" 1
215 echo
216 return 0
217 fi
218 printf "%-60s | %5d | ${green}OK${normal}" "$1" 1
219 echo
220 return 0
221}
222
223#
224# pubspecReplace: replace a specific version field in a YAML file
225# must be a top level "version" field in the yaml structure
226# did not find a package that preserves comments so this is
227# somewhat brain-dead, but it gets the job done
228# \param $1 filename to do replacements on
229# \returns 0 on success
230#
231
232function pubspecReplace
233{
234 replace "$1" "version: ${OLDVERSION}" "version: ${NEWVERSION}"
235}
236
237#
238# replace: replace occurrences of one string with another
239# the file specified must contain the old string at least once
240# in order to be successful.
241# \param $1 filename to do replacements on
242# \param $2 the "old" string to be replaced
243# \param $3 the "new" striing to replace it with
244# \returns 0 on success
245#
246function replace
247{
248 local result
249 local output
250 local oldString="$2"
251 local newString="$3"
252 local oldRegex=$(escapeVersion "${oldString}")
253 local count=$(grep -Ec "${oldRegex}" "$1")
254 local verbose
255 if [ $count -eq 0 ]; then
256 printf "%-60s | %5d | ${red}NOT FOUND${normal}: ${oldString}" "$1" 0
257 echo
258 return 1
259 elif [ ! -z "$DRYRUN" ]; then
260 printf "%-60s | %5d | MATCHES:" "$1" "$count"
261 echo
262 while read -r line; do
263 echo " > $(echo "$line" | sed "s/${oldRegex}/${reverse}${green}${oldString}${normal}/g")"
264 done < <(grep -E "${oldRegex}" "$1")
265 return 0
266 fi
267 output=$(sed -i "s/${oldRegex}/${newString}/g" "$1")
268 result=$?
269 if [ $result -ne 0 ]; then
270 printf "%-60s | %5d | ${red}ERROR${normal}: %s" "$1" "$count" "$output"
271 echo
272 return 1
273 fi
274 printf "%-60s | %5d | ${green}OK${normal}" "$1" "$count"
275 echo
276 return 0
277}
278
279#
280# simpleReplace: replace occurrences of ${OLDVERSION} with ${NEWVERSION}
281# the file specified must contain OLDVERSION at least once
282# in order to be successful.
283# \param $1 filename to do replacements on
284# \param $2 the "old" string to be replaced
285# \param $3 the "new" striing to replace it with
286# \returns 0 on success
287#
288function simpleReplace
289{
290 replace "$1" "${OLDVERSION}" "${NEWVERSION}"
291}
292
293echo ""
294echo "Apache Thrift Version Alignment Tool"
295echo "------------------------------------"
296echo ""
297echo "Previous Version: ${OLDVERSION}"
298echo " New Version: ${NEWVERSION}"
299echo ""
300echo "-------------------------------------------------------------+-------+----------------------"
301echo "Filename | Count | Status "
302echo "-------------------------------------------------------------+-------+----------------------"
303
304for file in $(echo "${!FILES[@]}" | sort); do
305 ${FILES[$file]} $file || exit $?
306done
307
308echo
309echo "Files that must be modified manually:"
310echo
311for manu in $(echo "${!MANUAL[@]}" | sort); do
312 echo " > ${yellow}${manu}${normal}"
313done
314
315exit 0