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