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