Jens Geyer | 4eee681 | 2023-02-06 23:40:56 +0100 | [diff] [blame] | 1 | #!/usr/bin/env bash |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 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 | |
| 43 | declare -A FILES |
| 44 | |
| 45 | # These files require a manual touch: |
James E. King III | e824efc | 2019-01-07 16:50:54 -0500 | [diff] [blame] | 46 | FILES[CHANGES.md]=manual |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 47 | FILES[debian/changelog]=manual |
| 48 | FILES[doap.rdf]=manual |
| 49 | |
| 50 | # These files can be updated automatically: |
| 51 | FILES[ApacheThrift.nuspec]=simpleReplace |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 52 | FILES[appveyor.yml]=simpleReplace |
| 53 | FILES[bower.json]=jsonReplace |
Jens Geyer | 56700e4 | 2020-02-22 16:51:51 +0100 | [diff] [blame] | 54 | FILES[CMakeLists.txt]=simpleReplace |
Jens Geyer | 7199741 | 2019-10-19 21:22:59 +0200 | [diff] [blame] | 55 | FILES[compiler/cpp/src/thrift/version.h]=simpleReplace |
Jens Geyer | 56700e4 | 2020-02-22 16:51:51 +0100 | [diff] [blame] | 56 | FILES[configure.ac]=configureReplace |
| 57 | FILES[contrib/Rebus/Properties/AssemblyInfo.cs]=simpleReplace |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 58 | FILES[contrib/thrift.spec]=simpleReplace |
Jens Geyer | 56700e4 | 2020-02-22 16:51:51 +0100 | [diff] [blame] | 59 | FILES[contrib/zeromq/csharp/AssemblyInfo.cs]=simpleReplace |
James Z.M. Gao | 93ae7af | 2021-01-06 11:51:41 +0800 | [diff] [blame] | 60 | FILES[contrib/thrift-maven-plugin/pom.xml]=pomReplace |
James E. King III | 234fb47 | 2019-01-13 23:19:18 -0500 | [diff] [blame] | 61 | FILES[doc/specs/idl.md]=simpleReplace |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 62 | FILES[lib/d/src/thrift/base.d]=simpleReplace |
| 63 | FILES[lib/dart/pubspec.yaml]=pubspecReplace |
| 64 | FILES[lib/delphi/src/Thrift.pas]=simpleReplace |
| 65 | FILES[lib/erl/src/thrift.app.src]=simpleReplace |
| 66 | FILES[lib/haxe/haxelib.json]=simpleReplace |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 67 | FILES[lib/java/gradle.properties]=simpleReplace |
Jens Geyer | 616df98 | 2019-10-19 22:08:13 +0200 | [diff] [blame] | 68 | FILES[lib/js/package-lock.json]=jsonReplace |
Jens Geyer | 56700e4 | 2020-02-22 16:51:51 +0100 | [diff] [blame] | 69 | FILES[lib/js/package.json]=jsonReplace |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 70 | FILES[lib/js/src/thrift.js]=simpleReplace |
| 71 | FILES[lib/lua/Thrift.lua]=simpleReplace |
Jens Geyer | 3fc0b8d | 2021-02-11 23:17:45 +0100 | [diff] [blame] | 72 | FILES[lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj]=simpleReplace |
| 73 | FILES[lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj]=simpleReplace |
| 74 | FILES[lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj]=simpleReplace |
Jens Geyer | aa0c8b3 | 2019-01-28 23:27:45 +0100 | [diff] [blame] | 75 | FILES[lib/netstd/Thrift/Properties/AssemblyInfo.cs]=simpleReplace |
Jens Geyer | b75e88a | 2019-10-17 21:56:39 +0200 | [diff] [blame] | 76 | FILES[lib/netstd/Thrift/Thrift.csproj]=simpleReplace |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 77 | FILES[lib/ocaml/_oasis]=simpleReplace |
| 78 | FILES[lib/perl/lib/Thrift.pm]=simpleReplace |
| 79 | FILES[lib/py/setup.py]=simpleReplace |
| 80 | FILES[lib/rb/thrift.gemspec]=simpleReplace |
| 81 | FILES[lib/rs/Cargo.toml]=simpleReplace |
| 82 | FILES[lib/st/package.xml]=simpleReplace |
James E. King III | d7c11ad | 2019-01-11 19:19:44 -0500 | [diff] [blame] | 83 | FILES[lib/swift/Sources/Thrift.swift]=simpleReplace |
James E. King III | 1735542 | 2019-01-11 23:06:08 -0500 | [diff] [blame] | 84 | FILES[lib/swift/Tests/ThriftTests/ThriftTests.swift]=simpleReplace |
Jens Geyer | 616df98 | 2019-10-19 22:08:13 +0200 | [diff] [blame] | 85 | FILES[lib/ts/package-lock.json]=jsonReplace |
Jens Geyer | 56700e4 | 2020-02-22 16:51:51 +0100 | [diff] [blame] | 86 | FILES[lib/ts/package.json]=jsonReplace |
Jens Geyer | 616df98 | 2019-10-19 22:08:13 +0200 | [diff] [blame] | 87 | FILES[package-lock.json]=jsonReplace |
Jens Geyer | 56700e4 | 2020-02-22 16:51:51 +0100 | [diff] [blame] | 88 | FILES[package.json]=jsonReplace |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 89 | FILES[sonar-project.properties]=simpleReplace |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 90 | FILES[test/dart/test_client/pubspec.yaml]=pubspecReplace |
| 91 | FILES[test/erl/src/thrift_test.app.src]=simpleReplace |
Jens Geyer | 3fc0b8d | 2021-02-11 23:17:45 +0100 | [diff] [blame] | 92 | FILES[test/netstd/Client/Client.csproj]=simpleReplace |
| 93 | FILES[test/netstd/Server/Server.csproj]=simpleReplace |
Jens Geyer | 56700e4 | 2020-02-22 16:51:51 +0100 | [diff] [blame] | 94 | FILES[Thrift.podspec]=simpleReplace |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 95 | FILES[tutorial/dart/client/pubspec.yaml]=pubspecReplace |
| 96 | FILES[tutorial/dart/console_client/pubspec.yaml]=pubspecReplace |
| 97 | FILES[tutorial/dart/server/pubspec.yaml]=pubspecReplace |
| 98 | FILES[tutorial/delphi/DelphiClient/DelphiClient.dproj]=simpleReplace |
| 99 | FILES[tutorial/delphi/DelphiServer/DelphiServer.dproj]=simpleReplace |
Jens Geyer | 3fc0b8d | 2021-02-11 23:17:45 +0100 | [diff] [blame] | 100 | FILES[tutorial/netstd/Client/Client.csproj]=simpleReplace |
| 101 | FILES[tutorial/netstd/Interfaces/Interfaces.csproj]=simpleReplace |
| 102 | FILES[tutorial/netstd/Server/Server.csproj]=simpleReplace |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 103 | FILES[tutorial/ocaml/_oasis]=simpleReplace |
| 104 | |
Jens Geyer | 56700e4 | 2020-02-22 16:51:51 +0100 | [diff] [blame] | 105 | |
| 106 | |
James E. King III | c9ac8d2 | 2019-01-07 16:46:45 -0500 | [diff] [blame] | 107 | if [ ! -f "CHANGES.md" ]; then |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 108 | >&2 echo "error: run veralign.sh while in the thrift root directory" |
| 109 | exit 1 |
| 110 | fi |
| 111 | |
| 112 | if [ $# -ne 2 ]; then |
| 113 | >&2 echo "usage: veralign.sh <oldVersion> <newVersion>" |
| 114 | exit 1 |
| 115 | fi |
| 116 | |
| 117 | jq --version 1>/dev/null 2>/dev/null |
| 118 | if [ $? -ne 0 ]; then |
| 119 | >&2 echo "error: the 'jq' package is not installed" |
| 120 | exit 1 |
| 121 | fi |
| 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 | # |
| 130 | function 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 | |
| 142 | OLDVERSION=$1 |
| 143 | NEWVERSION=$2 |
| 144 | validateVersion "${OLDVERSION}" || exit $? |
| 145 | validateVersion "${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 | # |
| 154 | function escapeVersion |
| 155 | { |
James Z.M. Gao | 93ae7af | 2021-01-06 11:51:41 +0800 | [diff] [blame] | 156 | echo "$(echo "$1" | sed 's/\./\\./g' | sed 's/\[/\\\[/g' | sed 's/\]/\\\]/g')" |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 157 | } |
| 158 | |
| 159 | # Set up verbose hilighting if running interactive |
| 160 | if [ "$(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) |
| 166 | fi |
| 167 | |
| 168 | declare -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 | # |
| 175 | function 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 | |
| 187 | function 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 | |
| 199 | function 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 | |
| 234 | function pubspecReplace |
| 235 | { |
| 236 | replace "$1" "version: ${OLDVERSION}" "version: ${NEWVERSION}" |
| 237 | } |
| 238 | |
| 239 | # |
James Z.M. Gao | 93ae7af | 2021-01-06 11:51:41 +0800 | [diff] [blame] | 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 | |
| 246 | function pomReplace |
| 247 | { |
| 248 | replace "$1" "^ <version>${OLDVERSION}<\/version>" " <version>${NEWVERSION}<\/version>" |
| 249 | } |
| 250 | |
| 251 | # |
James E. King III | ecebd77 | 2018-12-28 08:50:58 -0500 | [diff] [blame] | 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 | # |
| 260 | function 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 | # |
| 302 | function simpleReplace |
| 303 | { |
| 304 | replace "$1" "${OLDVERSION}" "${NEWVERSION}" |
| 305 | } |
| 306 | |
| 307 | echo "" |
| 308 | echo "Apache Thrift Version Alignment Tool" |
| 309 | echo "------------------------------------" |
| 310 | echo "" |
| 311 | echo "Previous Version: ${OLDVERSION}" |
| 312 | echo " New Version: ${NEWVERSION}" |
| 313 | echo "" |
| 314 | echo "-------------------------------------------------------------+-------+----------------------" |
| 315 | echo "Filename | Count | Status " |
| 316 | echo "-------------------------------------------------------------+-------+----------------------" |
| 317 | |
| 318 | for file in $(echo "${!FILES[@]}" | sort); do |
| 319 | ${FILES[$file]} $file || exit $? |
| 320 | done |
| 321 | |
| 322 | echo |
| 323 | echo "Files that must be modified manually:" |
| 324 | echo |
| 325 | for manu in $(echo "${!MANUAL[@]}" | sort); do |
| 326 | echo " > ${yellow}${manu}${normal}" |
| 327 | done |
| 328 | |
| 329 | exit 0 |