Titanium CLIでのビルドをサポートするTiNy(tn)

この記事は [Appcelerator Titanium Advent Calendar 2015](http://qiita.com/advent-calendar/2015/appc-titanium)
の19日目です。


おことわり
----------

以前自分のブログに書いた（ [Titanium CLIでのビルドをサポートするTiNy(tn) 2.x版](http://umi-uyura.hatenablog.com/entry/2015/04/24/220316) ）のですが、その後紆余曲折を経て、現在Appcelerator CLIにも対応した4.x系となっているので、改めて紹介させていただこうと思います。


TiNy(tn)とは
------------

TiNy CLI(tn)は、Titanium(Appcelerator) CLIで最も使用する頻度が高いと思われる `appc ti build (titanium build)` を使いやすくするためのツールです。

[FokkeZB/tn](https://github.com/FokkeZB/tn)


例えば、単純にiOSアプリをシミュレータで実行する際には以下のように実行できますが、

```
$ [appc] ti build --platform ios
```

TiNyを導入することで、これを

```
$ tn ios
```

のように実行することができるようになります。

頻繁に使うコマンドのタイプ数が減らすことができますし、よく使うパラメータを短縮形として登録しておき、それを組み合わせて使うこともできます。

シェルのaliasなどで似たようなことはできますが、数が多くなってくると管理が大変だと思いますので、そういった場合に使ってみても良いかと思います。

※本エントリの内容はAppcelerator CLI 5.1.0、Titanium CLI 5.0.5、およびTiNy 4.0.6をベースに書いています。


導入方法
--------

```
$ [sudo] npm install -g tn --unsafe-perm
```

**※注意事項※**

プロジェクトの名前は **TiNy CLI** のようですが、npmに登録されているパッケージ名は **tn** となります。また、npmには **tiny** という別のパッケージも登録されているので、間違えないように気をつけてください。


基本的な使い方
---------------

### `build` の省略

TiNyを導入すると、 `tn` コマンドが使えるようになります。これにより、 `tn` と打つだけで `[appc] ti build` の代わりになります。`tn` の後ろに `build` 以外のコマンドを打った場合は、通常通り、そのコマンドが実行されます。

```
$ tn ios        # `[appc] ti build --platform ios`
$ tn clean      # 通常通り、 `[appc] ti clean` が実行される
```

### recipeの実行

先にあげた例で `tn ios` と実行していますが、ここで指定している `ios` はrecipeと呼ばれているパラメータの一つで、 `--platform ios` のエイリアスになっています。

これらのrecipeと、既存の `[appc] ti (titanium)` コマンドのオプションを組み合わせて使うことができます。

```
$ tn android                    # `[appc] ti build --platform android`
$ tn retina --sim-type ipad     # `[appc] ti build --retina --platform ios --sim-type ipad`
```

こういった `[appc] ti (titanium)` コマンドのオプションの短縮形がrecipeとして組み込まれています。

組み込みrecipeの一覧は [GitHubのREADME](https://github.com/FokkeZB/tn#built-in-recipes) に掲載されている他、 `tn` コマンドで

```
$ tn list
```

と実行することでも確認できます。（これは後述するカスタムrecipeも含んだ一覧が出力されます）


### 複数のrecipeを組み合わせる

複数のrecipeを組み合わせる場合、2つ目以降の引数でのrecipe指定には `--` を付ける必要があります。

例えば、 `--platform ios` のエイリアスである `ios` と、 `--target device` のエイリアスである `device` を同時に使いたい場合は、以下のように実行します。

```
$ tn ios --device               # [appc] titanium build --platform ios --target device
```


カスタムrecipe
--------------

先に述べたとおり、recipeは自分で作ることもできます。

### カスタムrecipeの作り方

recipeの作成は `tn save` コマンドで行います。

```
$ tn save <recipe名> <展開するコマンド>
```

例えば、AppStoreリリース用のコマンドとして、プロビジョニングプロファイル( `--pp-uuid` )とデベロッパ名( `--distribution-name` )をrecipeとして登録しておくことで、

```
$ tn save dist-as --platform ios --target dist-appstore --pp-uuid XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX --distribution-name "Titanium Taro  (XXXXXXXXXX)"
```

以下のコマンドでリリース用のビルドを実行することができます。

```
$ tn dist-as
```

また他にも、カスタムrecipeに対して以下の様な操作を行うことができます。

```
$ tn save ios --target android  # 既存recipeの ios を上書き
$ tn rename ios confusing       # ios というrecipeを confusing に変更
$ tn remove confusing           # confusing というrecipeを削除
$ tn reset                      # カスタムrecipeをすべて削除する
```


### 設定ファイル

作成したカスタムrecipeは、Macであれば `~/.tn.json` に保存されているので、これを管理すれば、新しい環境でも同じレシピを使いまわすことができそうです。

また、カスタムrecipeを作成する際に `tn project save ...` といったように `project` を付けることで、設定ファイル `tn.json` がカレントディレクトリ内に作成されるので、プロジェクト単位に用意するといった使い方もできます。


### カスタムrecipeの例

#### iOS開発時のデベロッパ名、プロビジョニングプロファイルの指定

iOSアプリをデバイス向けにビルドする際には、プロビジョニングプロファイルとデベロッパ証明書による署名が必要となります。

Titanium CLIではビルド実行時に対話的に選択することができますが、毎回選ぶのも少し面倒ですので、あらかじめ使用するデベロッパ名やプロビジョニングプロファイルの組み合わせをrecipe化しておくと、対話インターフェイスを出さずに実行できます。

```
# recipe登録
$ tn save dev-build --platform ios --target device --pp-uuid XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX --developer-name "Titanium Taro  (XXXXXXXXXX)"

# 指定したプロビジョニングプロファイルとデベロッパ証明書を使ってビルド
$ tn dev-build
```

`--pp-uuid` でプロビジョニングプロファイルのUUIDを、 `--developer-name` でデベロッパ名を指定しておきます。


#### iOS/Android開発時のデバイス指定

Android開発では、エミュレータの仮想デバイスを作成する際に名前をつけることができますが、Genymotionを使う場合など何も考えずに作成すると、**"Google Nexus 5 - 4.4.4 - API 19 - 1080x1920"** のような長い名前になったりします。

また、iOS開発では、デバイスをUUIDで指定しなくてはならないため、これも覚えるのが大変です。

いずれも、実行するデバイスを指定するオプションとしては `--device-id` を使いますので、これも頻繁に使うものについてはrecipe化しておくと、実行が簡単になります。


```
# iPhone 6のシミュレータを登録
$ tn save iphon6 --platform ios --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

# iPhone 6のシミュレータで実行
$ tn iphone6        # [appc] ti build --platform ios --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
```

```
# Nexus 5のエミュレータ登録
$ tn save nexus5 --platform android --device-id "Google Nexus 5 - 4.4.4 - API 19 - 1080x1920"

# Nexus 5のエミュレータで実行
$ tn nexus5         # [appc] ti build --platform android --device-id "Google Nexus 5 - 4.4.4 - API 19 - 1080x1920"
```


### デバイス/シミュレータ/エミュレータ用recipeの登録機能

先ほどデバイス指定をカスタムrecipeとして登録しておくと便利ということを書きましたが、それを自動的に登録してくれる機能があります。

```
$ tn generate
```

これを実行すると、接続している端末や環境内にあるエミュレータ/シミュレータの情報から、以下のような感じで各デバイスを指定する際のカスタムrecipeを生成してくれます。

*AndroidエミュレータやGenymotionの場合*

```
nexus5-api15: --android --emulator --device-id Nexus5-API15
google-nexus-5-444-api-19-1080x1920: --android --emulator --device-id "Google Nexus 5 - 4.4.4 - API 19 - 1080x1920"
```

*iPhone端末（`Taro-no-iPhone`)の場合*

```
taro-no-iphone: --ios --device --device-id XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

*iPhoneシミュレータの場合*

```
ipad-2: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
ipad-2-ios71: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
ipad-2-ios84: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
ipad-air: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
ipad-air-2: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
ipad-air-ios71: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
ipad-air-ios84: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
ipad-pro: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
ipad-retina: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
ipad-retina-ios71: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
ipad-retina-ios84: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-4s: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-4s-ios71: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-4s-ios84: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-5: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-5-ios71: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-5-ios84: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-5s: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-5s-ios71: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-5s-ios84: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-6: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-6-ios84: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-6-plus: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-6-plus-ios84: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-6s: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
iphone-6s-plus: --ios --simulator --device-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
```

なお、名前にスペースなどが含まれている場合など、うまく検出できないケースもあるようでした。


alloy-smelter
-------------

同様のツールに [k0sukey氏](http://qiita.com/k0sukey) の [alloy-smelter](https://github.com/k0sukey/alloy-smelter) があります。

こちらは、 `smelter presets` で `ti build` に渡すプリセットを設定しておくことができます。また、他にもAlloyで生成したコントローラ/ビュー/スタイルのファイル名を一括変更したり、Resourcesフォルダ内も対象となるcleanがあったり、統計を取ったりと、多機能です。（ファイル名一括変更やResourcesクリーンなどは、最近AlloyやTitanium CLIでもサポートされてきたようですが）

それ以前からTiNyを使っていたこともあり、ビルドに関してはそっちを使っているものの、それ以外の機能も便利なので、併用していま・・・した。

・・・が、どうやら内部モジュールの影響か、MacのNode v0.12以降でインストール出来ないようなので、最近は使えていないのが少し残念です(/ω・＼)ﾁﾗｯ


まとめ
------

CLIでの開発は、コマンドやパラメータの組み合わせを覚えたり、打ち込んだりするのが大変だったりしますが、TiNyはそのあたりをサポートしてくれるので、便利です。MacBook Airなど非力なマシンで開発するとき、Appcelerator Studioではメモリの負担が大きいような場合などに活用できるかもしれません。



というわけで、明日は [ganezasanさん](http://qiita.com/ganezasan) です。


参考
----

* [FokkeZB/tn](https://github.com/FokkeZB/tn)
* [New TiNy version with support for AppC CLI | Fokke Zandbergen](http://fokkezb.nl/2015/04/24/new-tiny-version-with-support-for-appc-cli/)
* [Titanium Alloy プロジェクトでの開発のお供、alloy-smelter のお誘い - Qiita](http://qiita.com/k0sukey/items/23004cee75878ee3d3e7)