package.xml 生成ツールを作ってみました。

# はじめに
みなさま、はじめまして。宮本隆人([@takahito0508](https://twitter.com/takahito0508))です。
某企業にてSalesforceのエンジニアをしております。鎌倉市在住、休日の趣味はSalesforceやHerokuでのプログラミング、社内外でのボランティア活動、ガチで試合に勝つための卓球です。今年から都内のSalesforceイベントやmeetupにも足繁く通うようになりましたので、ぜひオフラインでSalesforceトークしましょう！

[Salesforce Platform Advent Calendar 2017](https://qiita.com/advent-calendar/2017/salesforce-platform) の17日目の投稿です。はじめての参加で緊張していますがよろしくお願いいたします。今回は、Salesforceのメタデータ資源に馴染みのあるかたがたへ届けたいアツい想いを綴った内容となります。全然馴染みのないかたがたにとっては全体的に「？？」な内容となる可能性がありますし、そこそこ馴染みのあるかたにとってもマニアックすぎて頭に入ってこない可能性もあることをお許しください。

# 作成したツール
今回ご紹介したいのはこのツールです。ぜひ使ってください！
[salesforce-manifest-generator](https://github.com/takahitomiyamoto/salesforce-manifest-generator/releases)

本投稿では、なぜこんなものを作ったのかの背景と、実際の使い方を述べさせていただきます。まだまだ経験が浅いので思い違いな部分も多々あるかと思います。ディスカッション大歓迎ですので、一番下のコメント欄か、私のtwitterアカウントまでお願いいたします。

# 既存ツールに対する考察
開発者コンソールではなく、Salesforceの資源をローカルにおとして開発作業をされているかたがたにとってはおなじみの「[package.xml](https://developer.salesforce.com/docs/atlas.ja-jp.api_meta.meta/api_meta/manifest_samples.htm)」ファイル。デプロイ担当者はこのファイルを元にして、sandboxからsandbox、sandboxから本番組織へとデプロイをしていくことになります。みなさまはこの大事なファイルを普段どのように準備していらっしゃいますか？

私の経験の範囲にはなりますが、有償ツール以外では以下の5択になるのではないでしょうか。
1. Eclipseの「[Force.com IDE](https://developer.salesforce.com/docs/atlas.en-us.eclipse.meta/eclipse/ide_pro_projects_delete.htm)」を利用する
2. VS CodeやSublimeTextやAtomと連携する「[MavensMate-Desktop](https://github.com/joeferraro/MavensMate-Desktop/releases)」を利用する
3. Antの「[Force.com Migration Tool](https://developer.salesforce.com/docs/atlas.ja-jp.daas.meta/daas/forcemigrationtool_listmetadata.htm)」を利用する
4. JSforceの「[jsforce-metadata-tools](https://github.com/jsforce/jsforce-metadata-tools)」を利用する
5. Salesforce DXの「[sfdx force:mdapi:retrieve](https://developer.salesforce.com/docs/atlas.ja-jp.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_create_from_existing.htm)」コマンドを利用する

それぞれをシチュエーションごとに使い分けている1ユーザとして、あくまでも "package.xml生成" の観点に絞った考察を独断的に述べていきたいと思います。

### 1番（Force.com IDE） vs 2番（MavensMate-Desktop）
まず、1番と2番については、コマンド操作ではなくGUI操作になりますので、そもそも作業スピードが落ちます。GUIが好きな人にとってはなんら問題ありませんし、自分も使ってるので否定もしませんが、ある程度開発経験を経てくると生産性に貪欲になってくることもあり、この点がデメリットとなります。

逆にメリットとしては、該当の組織に存在するメタデータタイプの種類を事前に知らなくてもいいという点です。メニューをクリックすれば勝手にツール上にメタデータタイプの一覧が表示されるので、そこから欲しいものだけ選ぶことができます。たとえば、その組織にtranslation資源が存在するか否かは、ツールの画面を見て確かめれば良いですし、確認のうえ欲しいものだけ選択することも可能です。後述しますが、これは3番、4番、5番のツールにはできない芸当です。ただし、メタデータタイプの選択の仕方によってはワイルドカード（＊）が適用されますので、by nameでメタデータをすべて指定したい場合には困ることになります。何十個もあるメタデータを1個1個チェックしていくのは手間がかかります。

もう少しdeep diveすると、1番は最新のAPIバージョンに対応するのが遅い、取得できないメタデータタイプがある、といったデメリットがある一方、2番は設定の範囲でAPIバージョンを自由に変更できる、取得できないメタデータタイプがない、といったメリットがあります。更に個人的には、EclipseとSalesforceの相性の悪さ（save to server時に画面がロックされることによる作業効率の極端な低下）のため、現在は2番一択で愛用しています。

しかし、惜しくも2番は開発終了が発表されており今後のエンハンスメントが行われませんので、Salesforceの今後のバージョンアップ次第では十分に動かなくなる可能性があるのが悩みの種です。ほんとうに残念ですね。そこで、1番に期待がかかるところなのですが、そもそも1番は今後も開発が続いていくのか、VS Codeの[sfdx拡張機能](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode)に一本化されていくのか、といったロードマップが気になるところです。

### 3番（Force.com Migration Tool） vs 4番（jsforce-metadata-tools）
3番と4番については、共にコマンドラインで操作できるため、一連の作業をスクリプトとして組みたい場合にとても重宝します。どの環境のどの資源がほしいのかをあらかじめ設定しておけば、Salesforce覚えたての子であっても単純にスクリプトファイルをダブルクリックしてもらうだけで品質の良い作業を再現できますし、人間の代わりにJenkinsさまなど自動化ツールに仕事を奪っていただくことで更に人間の仕事の生産性を高めることもできます。

3番も4番も、どちらも事前準備にはある程度のスキルが求められます。buildファイルをきっちり設計して想定してることをかたーくやらせるのが好みなら3番、柔軟な発想でやりたいことをばーっとスクリプトに落としていく、あるいはコンソールから対話形式にコマンドを打ち込んでいくのが好みなら4番、かなと考えています。個人的には、公式にサポートされてる安心感と、ほかのチームメンバーにやらせたときに品質をコントロールしやすいという感覚があるため、3番を使い続けています。

しかし、どちらにも共通して言えるのは、存在を把握できていないメタデータは取得できないという点です。3番であれば "metadataType"、4番であれば　"memberTypes" のパラメータに対して特定のメタデータ名を明記してコマンドを実行しなければ、対応するメタデータをpackage.xml内に含めることができません。

つまりこれは禅問答のようなもので、該当する組織内にどんなメタデータが存在しているのかを全量把握したいと思っても、少なくともApex資源は1個以上存在しているのかを事前に知ったうえでコマンドを実行しなければApex資源の一覧は得られないのです。これはマニアックなメタデータタイプになればなるほど困難を極めます。たとえば、AuraDefinitionBundleくらいなら1個以上あるのかないのかくらいを想像できるかもしれませんが、MilestoneTypeが果たしてあるのかないのかを事前に想像できるひとって、ごく少数だと思います。

結局、どうしても1番あるいは2番に頼る必要が生じます。まあ、複数のツールを使い続ける方針でもよいのですが、せっかくならもっと効率化できる方法を追求したい、この点がもっともクリティカルにツールを開発しようと決意したきっかけです。（もし、ここまでの認識に間違いがあれば、ぜひぜひご指摘・ご助言いただきたいです。）

### 5番（sfdx）の限界と期待
最後、5番については、適用範囲が限定される認識です。その組織内の管理パッケージあるいは未管理パッケージに含まれるメタデータの取得、あるいはscratch orgに対して自ら変更したメタデータのみの取得に限られるという理解です。そこはもっとつっこんで、ユーザ名とパスワードさえわかれば、その組織内のすべてのメタデータを取得できるようにしてほしいなあと今後のバージョンアップへ期待しつつ、待ってられないのでその期待する内容を今回の自作ツールに込めた次第です。

|No|ツール|操作方法|設定ファイル不要|すべてのタイプ取得可能|タイプの事前特定不要|公式サポート|
|:-:|:---|:-----:|:----------:|:---------------:|:--------------:|:-------:|
|1|Force.com IDE|GUI|:white_check_mark:||:white_check_mark:|:question:|
|2|MavensMate-Desktop|GUI|:white_check_mark:|:white_check_mark:|:white_check_mark:||
|3|Force.com Migration Tool|CLI||:white_check_mark:||:white_check_mark:|
|4|jsforce-metadata-tools|CLI|:white_check_mark:|:white_check_mark:|||
|5|sfdx|CLI|:white_check_mark:|||:white_check_mark:|


# 「salesforce manifest generator」のご紹介
前置きが長くなりました。このたび、該当組織のユーザ名とパスワードを指定すれば、その組織内のすべてのメタデータをby nameで含んだpackage.xmlを生成してくれるツールをJavaで開発し、GitHubへ公開しました。みなさまの開発作業の一助となることを切に願います。
[salesforce-manifest-generator](https://github.com/takahitomiyamoto/salesforce-manifest-generator/releases)

### 使い方（zipファイルから）
zipファイルをダウンロードします。
~~[salesforce-manifest-generator-v0.0.1.zip]()~~

~~[2018/08/03 追記] 最新バージョンは **v0.1.0** ですので、**v0.1.0** をダウンロードしてください。~~

~~[2018/12/29 追記] 最新バージョンは **v0.3.0** ですので、**v0.3.0** をダウンロードしてください。~~

[2019/08/26 追記] 最新バージョンは **v0.4.2** ですので、**v0.4.2** をダウンロードしてください。

https://twitter.com/takahito0508/status/1078956926468149248
[salesforce-manifest-generator-v0.4.2.zip](https://github.com/takahitomiyamoto/salesforce-manifest-generator/releases/tag/v0.4.2)

参照元：https://github.com/takahitomiyamoto/salesforce-manifest-generator/releases
<img width="1004" alt="salesforce-manifest-generator-release.png" src="https://qiita-image-store.s3.amazonaws.com/0/212555/0521bbaa-a642-32b4-bf78-5d4d96a5e295.png">

zipファイルを解凍します。
<img width="314" alt="salesforce-manifest-generator-unzip.png" src="https://qiita-image-store.s3.amazonaws.com/0/212555/e973bfdc-98ee-1330-5179-4a5fa2921ff3.png">

salesforce-manifest-generator/binの直下にcredentials.jsonを作成します。
<img width="307" alt="salesforce-manifest-generator-credentials.png" src="https://qiita-image-store.s3.amazonaws.com/0/212555/ce948470-7513-6d75-8caa-f6023ff83542.png">

[2019/05/09 追記] 最新バージョンではcredentials.jsonの構造を変更しています。

```json:credentials.json
{
    "credentials": {
        "username": "xxxxxxxxxx",
        "password": "xxxxxxxxxx",
        "orgType": "login",
        "apiVersion": 45.0,
        "os":"win",
        "exceptManagedPackage": false,
        "exceptUnmanagedPackage": false,
        "proxyHost": "http://myproxy.internal.company.com",
        "proxyPort": 8000
    }
}
```
|No|プロパティ名|内容|必須|備考|
|:-:|:-------|:--|:---|:--|
|1|username|ログインユーザ名|:white_check_mark:||
|2|password|ログインパスワード|:white_check_mark:|セキュリティトークンがある場合は含める|
|3|orgType|組織タイプ|:white_check_mark:|login: productionおよびdeveloper<br>test: sandbox|
|4|apiVersion|APIバージョン|:white_check_mark:||
|5|os|OS名|:white_check_mark:|win: Windows用(Shift_JIS)<br>mac: Mac用(UTF-8)|
|6|exceptManagedPackage|管理パッケージ排除フラグ|:white_check_mark:|true または false|
|7|exceptUnmanagedPackage|未管理パッケージ排除フラグ|:white_check_mark:|true または false|
|8|proxyHost|プロキシホスト||プロキシサーバのホスト名|
|9|proxyPort|プロキシポート||プロキシサーバのポート|

~~[2018/08/03 追記] 最新バージョン **v0.1.0** で、JSON構造が少し変更になりました。~~
~~[2018/12/28 追記] 最新バージョン **v0.3.0** で、JSON構造が少し変更になりました。~~
詳細は [README](https://github.com/takahitomiyamoto/salesforce-manifest-generator#change-your-credentials) をご覧ください。

スクリプトファイルをダブルクリックして実行し、処理が完了するまでしばらく待機します。
これによりpackage.xmlが直下に生成されるはずですのでご確認ください。

[2019/05/09 追記] 最新バージョンではpackage.xmlのほかに次のファイルも生成されます:

- package_managed.xml: 管理パッケージおよびロック解除済みパッケージの資源
- package_unmanaged.xml: 未管理パッケージの資源


### 使い方（ソースコードから）
ソースコードをローカルにおとします。
> git clone https://github.com/takahitomiyamoto/salesforce-manifest-generator.git

gradleをインストールしていなければインストールします。
> brew install gradle

gradleでビルドします。
> gradle build

credentials_sample.jsonをcredentials.jsonにリネームします。
> cd salesforce-manifest-generator
> mv credentials_sample.json credentials.json

credentials.jsonの内容を適切に変更します。（上記同様）

gradleで実行します。
> gradle run

処理が完了するまでしばらく待機します。
これによりpackage.xmlが直下に生成されるはずですのでご確認ください。

[2018/12/28 追記] 最新バージョン **v0.3.0** で機能追加があり、package.xmlの中身から未管理パッケージや管理パッケージの資源を分離できるようにしました。
詳細は [README](https://github.com/takahitomiyamoto/salesforce-manifest-generator/blob/master/README.md) をご覧ください。

# おわりに
手順に不具合などございましたらご遠慮なくコンタクトください。コメント欄か、私のtwitterアカウントまでお願いいたします。

これからもSalesforce開発に関するツールやサンプルコードをどんどん公開していきたいと思いますので、ぜひ今後ともフォローいただければ幸いです。どうぞよろしくお願いいたします。

- Twitter: [@takahito0508](https://twitter.com/takahito0508)
- GitHub: [takahitomiyamoto](https://github.com/takahitomiyamoto)