モバイルアプリを作っていると,開発版 (development) とテスター用 (staging) と製品版 (production) とかを分けてアプリ作りたくなりますよね.
ならないとしたら,今すぐこの記事を読むのをやめて病院に行って下さい.
Titanium CLI で ti build
とかをする直前と直後に,以下のシェルスクリプトを実行する Makefile なり Gruntfile なりを作ってやって下さい.
#! /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
#! /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 は
hostname: my.development.com
となっていることを想定しています.ファイル env はバージョン管理で無視設定にしておくと良いと思います.
また,tiapp.xml にはそもそも production を想定したものが書かれているとします.
ちなみに,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 のコード内で
var s = Ti.App.Properties.getString('varname');
alert(s); // alert "mystring"
という感じで取得出来ます.
以上をまとめて,作るべき 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
を追加するようにするとか.