1x#!/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: 46FILES[CHANGES.md]=manual 47FILES[debian/changelog]=manual 48FILES[doap.rdf]=manual 49 50# These files can be updated automatically: 51FILES[ApacheThrift.nuspec]=simpleReplace 52FILES[appveyor.yml]=simpleReplace 53FILES[bower.json]=jsonReplace 54FILES[CMakeLists.txt]=simpleReplace 55FILES[compiler/cpp/src/thrift/version.h]=simpleReplace 56FILES[configure.ac]=configureReplace 57FILES[contrib/Rebus/Properties/AssemblyInfo.cs]=simpleReplace 58FILES[contrib/thrift.spec]=simpleReplace 59FILES[contrib/zeromq/csharp/AssemblyInfo.cs]=simpleReplace 60FILES[contrib/thrift-maven-plugin/pom.xml]=pomReplace 61FILES[doc/specs/idl.md]=simpleReplace 62FILES[lib/d/src/thrift/base.d]=simpleReplace 63FILES[lib/dart/pubspec.yaml]=pubspecReplace 64FILES[lib/delphi/src/Thrift.pas]=simpleReplace 65FILES[lib/erl/src/thrift.app.src]=simpleReplace 66FILES[lib/haxe/haxelib.json]=simpleReplace 67FILES[lib/java/gradle.properties]=simpleReplace 68FILES[lib/js/package-lock.json]=jsonReplace 69FILES[lib/js/package.json]=jsonReplace 70FILES[lib/js/src/thrift.js]=simpleReplace 71FILES[lib/lua/Thrift.lua]=simpleReplace 72FILES[lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj]=simpleReplace 73FILES[lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj]=simpleReplace 74FILES[lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj]=simpleReplace 75FILES[lib/netstd/Thrift/Properties/AssemblyInfo.cs]=simpleReplace 76FILES[lib/netstd/Thrift/Thrift.csproj]=simpleReplace 77FILES[lib/ocaml/_oasis]=simpleReplace 78FILES[lib/perl/lib/Thrift.pm]=simpleReplace 79FILES[lib/py/setup.py]=simpleReplace 80FILES[lib/rb/thrift.gemspec]=simpleReplace 81FILES[lib/rs/Cargo.toml]=simpleReplace 82FILES[lib/st/package.xml]=simpleReplace 83FILES[lib/swift/Sources/Thrift.swift]=simpleReplace 84FILES[lib/swift/Tests/ThriftTests/ThriftTests.swift]=simpleReplace 85FILES[lib/ts/package-lock.json]=jsonReplace 86FILES[lib/ts/package.json]=jsonReplace 87FILES[package-lock.json]=jsonReplace 88FILES[package.json]=jsonReplace 89FILES[sonar-project.properties]=simpleReplace 90FILES[test/dart/test_client/pubspec.yaml]=pubspecReplace 91FILES[test/erl/src/thrift_test.app.src]=simpleReplace 92FILES[test/netstd/Client/Client.csproj]=simpleReplace 93FILES[test/netstd/Server/Server.csproj]=simpleReplace 94FILES[Thrift.podspec]=simpleReplace 95FILES[tutorial/dart/client/pubspec.yaml]=pubspecReplace 96FILES[tutorial/dart/console_client/pubspec.yaml]=pubspecReplace 97FILES[tutorial/dart/server/pubspec.yaml]=pubspecReplace 98FILES[tutorial/delphi/DelphiClient/DelphiClient.dproj]=simpleReplace 99FILES[tutorial/delphi/DelphiServer/DelphiServer.dproj]=simpleReplace 100FILES[tutorial/netstd/Client/Client.csproj]=simpleReplace 101FILES[tutorial/netstd/Interfaces/Interfaces.csproj]=simpleReplace 102FILES[tutorial/netstd/Server/Server.csproj]=simpleReplace 103FILES[tutorial/ocaml/_oasis]=simpleReplace 104 105 106 107if [ ! -f "CHANGES.md" ]; then 108 >&2 echo "error: run veralign.sh while in the thrift root directory" 109 exit 1 110fi 111 112if [ $# -ne 2 ]; then 113 >&2 echo "usage: veralign.sh <oldVersion> <newVersion>" 114 exit 1 115fi 116 117jq --version 1>/dev/null 2>/dev/null 118if [ $? -ne 0 ]; then 119 >&2 echo "error: the 'jq' package is not installed" 120 exit 1 121fi 122 123# 124# validateVersion: check that a version matches the major.minor.patch 125# format which is the lowest common denominator supported by all 126# project systems. 127# \param $1 the version 128# \returns 0 if the version is compliant 129# 130function validateVersion 131{ 132 local result 133 local valid 134 valid=$(echo "$1" | sed '/^[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+$/!{q22}') 135 result=$? 136 if [ $result -eq 22 ]; then 137 >&2 echo "error: version '$1' does not conform to the required major.minor.patch format" 138 return ${result} 139 fi 140} 141 142OLDVERSION=$1 143NEWVERSION=$2 144validateVersion "${OLDVERSION}" || exit $? 145validateVersion "${NEWVERSION}" || exit $? 146 147# 148# escapeVersion: escape the version for use as a sed search 149# \param $1 the version to escape 150# \output the escaped string 151# \returns 0 152# \example VERSEARCH=$(escapeVersion "[1.0.0]"); echo $VERSEARCH; => "\[1\.0\.0\]" 153# 154function escapeVersion 155{ 156 echo "$(echo "$1" | sed 's/\./\\./g' | sed 's/\[/\\\[/g' | sed 's/\]/\\\]/g')" 157} 158 159# Set up verbose hilighting if running interactive 160if [ "$(tput colors)" -ne 0 ]; then 161 reverse=$(tput rev) 162 red=$(tput setaf 1) 163 green=$(tput setaf 2) 164 yellow=$(tput setaf 3) 165 normal=$(tput sgr0) 166fi 167 168declare -A MANUAL 169 170# 171# manual: note that update of said file is manual 172# \param $1 filename to do replacements on 173# \returns 0 174# 175function manual 176{ 177 MANUAL["$1"]="" 178 return 0 179} 180 181# 182# configureReplace: replace the AC_INIT field in configure.ac 183# \param $1 filename to do replacements on 184# \returns 0 on success 185# 186 187function configureReplace 188{ 189 replace "$1" "[thrift], [${OLDVERSION}]" "[thrift], [${NEWVERSION}]" 190} 191 192# 193# jsonReplace: replace a specific version field in a JSON file 194# must be a top level "version" field in the json structure 195# \param $1 filename to do replacements on 196# \returns 0 on success 197# 198 199function jsonReplace 200{ 201 local result 202 local output 203 if [ ! -z "$DRYRUN" ]; then 204 output=$(jq -e ".version" "$1") 205 else 206 output=$(jq -e ".version = \"${NEWVERSION}\"" "$1" > tmp.$$.json && mv tmp.$$.json "$1") 207 fi 208 result=$? 209 if [ $? -ne 0 ]; then 210 printf "%-60s | %5d | ${red}ERROR${normal}: version tag not found" "$1" "$count" 211 echo 212 return 1 213 elif [ ! -z "$DRYRUN" ]; then 214 output=${output%\"} 215 output=${output#\"} 216 printf "%-60s | %5d | MATCHES: version: \"${reverse}${green}${output}${normal}\"" "$1" 1 217 echo 218 return 0 219 fi 220 printf "%-60s | %5d | ${green}OK${normal}" "$1" 1 221 echo 222 return 0 223} 224 225# 226# pubspecReplace: replace a specific version field in a YAML file 227# must be a top level "version" field in the yaml structure 228# did not find a package that preserves comments so this is 229# somewhat brain-dead, but it gets the job done 230# \param $1 filename to do replacements on 231# \returns 0 on success 232# 233 234function pubspecReplace 235{ 236 replace "$1" "version: ${OLDVERSION}" "version: ${NEWVERSION}" 237} 238 239# 240# pomReplace: replace a specific version field in a maven pom file 241# must be a top level "version" field in the xml structure 242# \param $1 filename to do replacements on 243# \returns 0 on success 244# 245 246function pomReplace 247{ 248 replace "$1" "^ <version>${OLDVERSION}<\/version>" " <version>${NEWVERSION}<\/version>" 249} 250 251# 252# replace: replace occurrences of one string with another 253# the file specified must contain the old string at least once 254# in order to be successful. 255# \param $1 filename to do replacements on 256# \param $2 the "old" string to be replaced 257# \param $3 the "new" striing to replace it with 258# \returns 0 on success 259# 260function replace 261{ 262 local result 263 local output 264 local oldString="$2" 265 local newString="$3" 266 local oldRegex=$(escapeVersion "${oldString}") 267 local count=$(grep -Ec "${oldRegex}" "$1") 268 local verbose 269 if [ $count -eq 0 ]; then 270 printf "%-60s | %5d | ${red}NOT FOUND${normal}: ${oldString}" "$1" 0 271 echo 272 return 1 273 elif [ ! -z "$DRYRUN" ]; then 274 printf "%-60s | %5d | MATCHES:" "$1" "$count" 275 echo 276 while read -r line; do 277 echo " > $(echo "$line" | sed "s/${oldRegex}/${reverse}${green}${oldString}${normal}/g")" 278 done < <(grep -E "${oldRegex}" "$1") 279 return 0 280 fi 281 output=$(sed -i "s/${oldRegex}/${newString}/g" "$1") 282 result=$? 283 if [ $result -ne 0 ]; then 284 printf "%-60s | %5d | ${red}ERROR${normal}: %s" "$1" "$count" "$output" 285 echo 286 return 1 287 fi 288 printf "%-60s | %5d | ${green}OK${normal}" "$1" "$count" 289 echo 290 return 0 291} 292 293# 294# simpleReplace: replace occurrences of ${OLDVERSION} with ${NEWVERSION} 295# the file specified must contain OLDVERSION at least once 296# in order to be successful. 297# \param $1 filename to do replacements on 298# \param $2 the "old" string to be replaced 299# \param $3 the "new" striing to replace it with 300# \returns 0 on success 301# 302function simpleReplace 303{ 304 replace "$1" "${OLDVERSION}" "${NEWVERSION}" 305} 306 307echo "" 308echo "Apache Thrift Version Alignment Tool" 309echo "------------------------------------" 310echo "" 311echo "Previous Version: ${OLDVERSION}" 312echo " New Version: ${NEWVERSION}" 313echo "" 314echo "-------------------------------------------------------------+-------+----------------------" 315echo "Filename | Count | Status " 316echo "-------------------------------------------------------------+-------+----------------------" 317 318for file in $(echo "${!FILES[@]}" | sort); do 319 ${FILES[$file]} $file || exit $? 320done 321 322echo 323echo "Files that must be modified manually:" 324echo 325for manu in $(echo "${!MANUAL[@]}" | sort); do 326 echo " > ${yellow}${manu}${normal}" 327done 328 329exit 0 330