tiapp.xml を切り替えるシェルスクリプト書いたし

モバイルアプリを作っていると，開発版 (development) とテスター用 (staging) と製品版 (production) とかを分けてアプリ作りたくなりますよね．

[ならないとしたら，今すぐこの記事を読むのをやめて病院に行って下さい](http://mattn.kaoriya.net/software/lang/ruby/20130110212633.htm)．

Titanium CLI で `ti build` とかをする直前と直後に，以下のシェルスクリプトを実行する Makefile なり Gruntfile なりを作ってやって下さい．

```sh:tiapp_xml-converter
#! /bin/sh

BUILD_TYPE=$1
if [ -z "$BUILD_TYPE" ]; then
  BUILD_TYPE=production
fi

if [ \
  $BUILD_TYPE != 'development' -a \
  $BUILD_TYPE != 'staging' -a \
  $BUILD_TYPE != 'production' \
]; then
  echo 'the argument should be in [development, staging, production]' 1>&2
  exit 1
fi

if [ $BUILD_TYPE = 'development' -a ! -e env ]; then
  echo "local environment file \"env\" doesn't exist" 1>&2
  exit 1
fi

if [ $BUILD_TYPE = 'development' ]; then
  HOSTNAME=$(cat env | grep 'hostname:' | awk '{print $2}')
elif [ $BUILD_TYPE = 'staging' ]; then
  HOSTNAME=staging.example.com
fi

if [ $BUILD_TYPE != 'production' ]; then
  cp tiapp.xml tiapp.xml.bk
  sed -e "s/<name>\(.*\?\)<\/name>/<name>\1${BUILD_TYPE}<\/name>/" tiapp.xml -i
  sed -e "s/<id>\(.*\?\)<\/id>/<id>\1${BUILD_TYPE}<\/id>/" tiapp.xml -i
  sed -e "s/<property name=\"appenv\" type=\"string\">.*\?<\/property>/<property name=\"appenv\" type=\"string\">${BUILD_TYPE}<\/property>/" tiapp.xml -i
  sed -e "s/<property name=\"hostname\" type=\"string\">.*\?<\/property>/<property name=\"hostname\" type=\"string\">${HOSTNAME}<\/property>/" tiapp.xml -i
fi
```

```sh:tiapp_xml-reverter
#! /bin/sh

if [ -e tiapp.xml.bk ]; then
  mv tiapp.xml.bk tiapp.xml
fi
```

何が行われるかというと，引数で development か staging か production (production のみ省略可) の文字列を渡してやると，id と name を sed コマンドで書き換え (末尾に development や staging を追加するだけ)，その他 property をやはり sed 使ったりなんかしたりして書き換えてくれるだけです．で，書き換える前にバックアップ取っておいてビルドが終わったら再び元の状態に戻すだけです．

特に自分が一番やりたかったことは，何らかのサーバアプリケーションと連携する際に，ホスト名を開発者ごとに，もっと言うと開発環境ごとに変えるということでした．ローカル IP にしてもいいし，Heroku なり VPS なりにしてもいいし…　ということがやりたかったのです．

で，この辺からが最も車輪の再発明・再実装，と言うか劣化車輪の発明を恐れているところなのですが…

引数に development を渡した際には，`env` というファイルを読み込んでそこから `hostname: my.development.com` という YAML っぽい形式の行を探してそれを awk で切り取る…　ということをしています．何ともアレ気ですけど，シェルスクリプトだけでファイル読み取ってパースして…　は割と頑張るの無駄っぽいなと思ってこう実装したまでです．マサカリ，「それ○○で出来るよ」コメント，覚悟してます．

ちなみにこの状態でのファイル env は

```plaintext:env
hostname: my.development.com
```

となっていることを想定しています．ファイル env はバージョン管理で無視設定にしておくと良いと思います．

また，tiapp.xml にはそもそも production を想定したものが書かれているとします．

ちなみに，tiapp.xml 内で

```xml:tiapp.xml
<?xml version="1.0" encoding="UTF-8"?>
<ti:app xmlns:ti="http://ti.appcelerator.org">
  ...
  <property name="varname" type="string">mystring</property>
  ...
</ti:app>
```

として作った情報は，アプリの JavaScript のコード内で

```javascript
var s = Ti.App.Properties.getString('varname');
alert(s); // alert "mystring"
```

という感じで取得出来ます．

以上をまとめて，作るべき build.sh 的なブツは以下のような感じです．

```sh:build.sh
#! /bin/sh

./tiapp_xml-converter $1
ti build                 # ここは各自でちゃんと書いてね
./tiapp_xml-reverter
```

development としてビルドしたければ `./build.sh development`，staging としてビルドしたければ `./build.sh staging`，production としてビルドしたければ `./build.sh` or `./build.sh production` とする感じです．

ところでそもそも Titanium SDK には Build-Type って概念があるんですけど，これがどういうわけか (実験したのだいぶ前なので覚えてないというのもありますが) 上手く動いてくれませんでした．なのである意味仕方なくこんな手法採ったのですが…　そっちで何か解決出来る方法もご存知の方居ましたらご教授下さると幸いです．

あとちょこちょこ工夫すれば development を更に小分けにすることも出来るはずです．というかいくらでも小分けに出来るはず．HOSTNAME を読み取って設定している箇所で，他にも `user: ka` みたいな行も読むようにして，`developmentka` を追加するようにするとか．