Bashでバージョン番号をインクリメントする

eyecatch-bash

アプリのリリース作業において、ファイル管理しているバージョン番号をインクリメントする作業が往々にして発生します。 手動更新は面倒な上にヒューマンエラーのリスクも高まります。

そこで Bash でバージョン番号をインクリメントする方法を紹介します。

やりたいこと

  • major.minor で採番されているバージョン番号に対して、Bash で minor の数字を一つ増やす
  • Bash の知識をあまり想定せず、わかりやすさを重視

実行イメージ

$ CUR_VERSION=1.9                 # なにかコマンドを実行して現在のバージョン番号を取得
$ NEW_VERSION=Bash でゴニョゴニョ # ← 今回のメイン
$ echo $NEW_VERSION               # バージョン番号がインクリメントしていることを確認
1.10

案1: IFS を修正

実行例

$ CUR_VERSION=1.9
$ NEW_VERSION=`echo $CUR_VERSION | ( IFS=".$IFS" ; read a b && echo $a.$((b + 1)) )`
$ echo $NEW_VERSION
1.10

処理の流れ

  1. バージョン番号のセパレーターをIFSに追加
  2. バージョン番号を数字ごとに変数に格納
  3. minor 番号をインクリメントして、セパレーターで結合し、バージョン番号に復元

IFS について

sh などのシェルでは文字列をトークナイズする internal field separator(IFS) が環境変数で定義されており、Bash のデフォルトは

  • 半角スペース
  • タブ
  • 改行

です。

IFS=".$IFS" とすることでこの IFS にバージョニングのセパレーターである「.」を追加し、バージョン番号を各数字の塊ごとに分割します。

分割した文字列は read コマンドで変数に格納します。

数字のインクリメント

最後に minor 番号をインクリメントします。

Bash では $((EXPRESSION))arithmetic expansion を表します。

$((b + 1)) とすることで、b をインクリメントします。

変数 val の値を一つ増やには、以下の方法があります。

(()) を利用

$ new_val=$((val+1))    # 今回利用
または
$ new_val=$(($val+1))

backtick を利用

$ new_val=`expr $val + 1`

let を利用

$ let new_val=val+1

案2:配列を利用

案1では分割した文字列を read で各変数に格納しました。 案2では配列に格納します。

実行例

$ CUR_VERSION=1.9
$ a=( ${CUR_VERSION//./ } )
$ ((a[1]++))
$ NEW_VERSION=${a[0]}.${a[1]}
$ echo $NEW_VERSION
1.10

処理の流れ

  1. バージョン番号を数字毎に分割して配列に格納
  2. minor 番号をインクリメント
  3. 配列をセパレーターで結合し、バージョン番号に復元

文字列の置換

${variable//pattern/replacement} で変数の文字列置換が可能です。

${CUR_VERSION//./ } では、バージョン番号のセパレーター「.」を IFS の一つである「半角スペース」に置換しています。

実際にやってみましょう

$ foo="a.b.c"
$ echo ${foo//./|}
a|b|c

文字列を分割して配列に格納

a=( 文字列 ) とすると、文字列を IFS で分割し、配列(a)に格納します。

実際にやってみましょう。

$ foo="a b c"    # セパレーターは「半角スペース」
$ arr=( $foo )   # 配列化
$ echo $arr
a
$ echo ${arr[0]} # Bashの配列は 0-index
a
$ echo ${arr[1]}
b

a=( ${CUR_VERSION//./ } ) では、セパレーターを IFS のものに置換した上で配列化しています。

まとめ

今回はバージョン番号を Bash でインクリメントする方法を2種類紹介しました。

地味な定形作業をスクリプト化しておくことと、リリース作業の負荷軽減が期待できます。

参考

AWS Cloud Roadshow 2017 福岡