Allzpark ランチャ作成フレームワーク の紹介

皆様ごきげんよう、あなたの Maya をエレキネット！なにもンなんじゃ？ *Maya Advent Calendar 2022 Day23* の時間でーす。この記事では CG・VFX・ゲーム業界での使用を主眼とした `ランチャを作成するためのフレームワーク` である [Allzpark](https://allzpark.com/) (https://allzpark.com/) の紹介をおこなう。なお文中にでてくるファイル類は https://github.com/yamahigashi/QiitaMayaAdventCalendar2022 にあげておいた。必要に応じて [zipでDL](https://github.com/yamahigashi/QiitaMayaAdventCalendar2022/archive/refs/heads/main.zip) し参考にしていただきたい。maya関係なくなくないかって？ハハッ

# Allzpark とは
Marcus Ottosson氏らによりOSSとして開発されている、下記に解説する ***ランチャ*** を作成するためのフレームワークである。以下のような特徴をもつ
 * GUI を通じた操作
 * ランチャ内容やカテゴリをカスタマイズ
 * Windows、Mac、Linux で動作
 * 見た目や感触をカスタマイズ

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17220/8c7706ed-9d24-bc79-75e1-1e5820c3bc54.png">

## ランチャとは
まずは一般的なランチャの役割について述べる。`ランチャ` とは業務を行ううえでのパイプラインを構成するための `入り口` となる重要なツールである。つまり以下のような機能を持つ
* （プロジェクトに応じ）複数の環境をきりかえ
* （プロジェクトに応じ）環境を整える
* （プロジェクトに応じ）ツールを起動する

参加する人間・機械が円滑に作業を行えるよう支援するものである。卑近な例では、「このランチャから起動すれば Maya やフォトショがいい感じにプラグインやそのほかいろいろ設定された状態で起動・動作しほかのソフトやシステムとも勝手に協調するようになっている」

繰り返し *プロジェクトに応じ* と記載しているが、これは単一プロジェクトの利用者にとっては一見メリットではなく、複数プロジェクトでの利用者、むしろ開発者にとって直接の益であるように見える。だがこれにより、多数の利用者へ統一した環境の提供が可能となるため、単一のプロジェクトでの使用者にとっても利点となるだろう。

:::note info
**パイプライン** の役割や詳しい解説については、日本CGサービスの痴山紘史さんによる CGWORLD の以下の記事、および連載をご覧いただくとより良いだろう。 https://cgworld.jp/regular/202005-chiyama-22-2.html
:::

では、これらの機能を具体的にどのように実現するのかについて触れていこう。

## ランチャの機能
プロジェクトに応じ *環境を切り替える*、 *環境を整える* 

とはどういうことなのか？ *ツール や ソフト* というのはもちろん1個で済むわけでなく、さらに同じツールであっても複数のバージョンが存在する。この中から適切なものを選択し、使用可能な状態にしてやる必要がある。端折るがこれには ***環境変数*** を利用する。数多あるファイルやフォルダのなかから、「*あなたに必要なものはこれとこれですよ*」と起動するツールに環境変数を通じ伝えてやるわけだ。 *ツールを起動する* とは ***コマンドを実行する*** ことに他ならない。つまり **各種環境変数を設定してやった状態で、特定のコマンドをたたく** というのがランチャの実態である。

例えば Maya を例にとってみよう。mayaの解する環境変数は https://help.autodesk.com/view/MAYAUL/2023/ENU/?guid=GUID-925EB3B5-1839-45ED-AA2E-3184E3A45AC7 から続くセクションに大量に並んでいるのだが、おそらく皆様になじみ深いのは

``` bat
SET MAYA_PLUG_IN_PATH=C:\sample\plug-ins
SET MAYA_SCRIPT_PATH=C:\sample\scripts
SET MAYA_MODULE_PATH=C:\sample\modules
```
あたりだろう。事前にこれらの変数に値を与えた状態で 

``` bat
SET PATH=C:\Program Files\Autodesk\Maya2023\bin;%PATH%
```
`PATH` を通してやり
```bat
maya.exe
```
とコマンドをたたき maya を起動してやるとプラグインやスクリプトが使用可能になっている。さらには所定の位置に `userSetup.mel` `userSetup.py` を配置してやることで、起動時に自動処理を走らせることができ、必要なお膳立てを完了することができる。


**環境変数** を設定し起動するだけでよいわけだ。だが、現実のプロジェクツにおいてはこのように単純ではなく、複数の環境に向けてツールを作成し、複数のソフトを用意する必要がある。場合によってあい反するバージョン、混成すると不具合を起こす組み合わせを取り扱わなくてはならない[^1]。

[^1]: わかりやすいところだと maya2020 / 2022 / 2023 で pythonバージョン全部違う。maya内であれば maya module のバージョン分け機能でいいのだが、今回は汎用的なシステムの話をしたいのです

そこでこういった状況をいい感じに管理するための仕組み、***パッケージ管理ソフト*** というものの出番となる。一連の環境変数やファイル、および設定を「***パッケージ***」として扱いし、それらを足したり引いたり、組み合わせたりするための仕組みだ。allzpark ではこのために、ASWF[^ASWF]による [**Rez** (https://github.com/AcademySoftwareFoundation/rez/wiki)]( https://github.com/AcademySoftwareFoundation/rez/wiki) [^Rez] を利用している。


ではパッケージ管理ソフトについてもうすこし詳しく見てみよう


## 「パッケージ管理」とは
環境変数やファイル、設定情報を一つのパッケージとしてカプセル化することで、*バージョンを管理*し *依存関係を管理*し、 各パッケージを*独立* して扱うことを可能にする。![](https://user-images.githubusercontent.com/2152766/61705822-7d1ad980-ad3e-11e9-81b3-473e8ac4e7c6.gif) 画像は https://allzpark.com/ より引用。ソフトに応じ依存パッケージが選択されている様子がわかる。


:::note info
**Rez** と似たような OSSで利用可能なパッケージ管理ソフトとして Blur studio の [**Hab** (https://github.com/blurstudio/hab)](https://github.com/blurstudio/hab), PeregrineLabs の [**Ecosystem** (https://github.com/PeregrineLabs/Ecosystem)](https://github.com/PeregrineLabs/Ecosystem) などがある。Ecosystem については GUNCY'S 野澤徹也さんの https://www.slideshare.net/tetsuyanozawa3/creative-conference-2017 の資料8ページからを参照されると良い。

使用目的が違うが CMake といったビルド構成管理システムも複数の環境に向けて特定のタスクをこなすためのお膳立てを行うという点で共通している。
:::

パッケージを管理するため対となる設定ファイルを用意し、このファイルに
 - 名前
 - バージョン番号
 - 依存関係
 - バリエーション

を記述することで、複数のパッケージをグループとして扱い、その依存関係の解決を管理する。

**allzpark** がベースとしている **Rez** では設定ファイルを Python で記述する。設定ファイルには上記の情報以外にも、そのパッケージがインストールするファイルやコマンド、その他の詳細を記述することができ、これらの設定ファイルを読み込んで、アプリケーションを実行するために必要な環境を自動的に構築してくれる。さらには、 *本稿では扱わないのだが* 、必要なパッケージを自動的にダウンロードしてインストール・ビルドしたり、既存のパッケージをアンインストールしたりといった開発業務での利用も可能だ。

[^Rez]: **Rez** とは
 Allan Johns氏により開発されのちにOSSとなり現在 ASFW財団により開発が進められている 

[^ASWF]: **Academy Software Foundation (ASWF)** とは
Academy of Motion Picture Arts and Sciences（いわゆるオスカー） と Linux Foundation により設立された、映画やメディア産業のOSSプロジェクトのサポートを行うための財団。また、映像制作、視覚効果、アニメーション、サウンドの技術に関するリソースを広く共有する開発者のためのコミュニティとなっている。MaterialX, OpenVDB, OpenColorIO, OpenEXR, OpenCue, OpenTimelineIO, Open Shading Language, Rezといったプロジェクトのホストとなっており、USDのワーキンググループの主催も行っている。詳細については、https://www.aswf.io 参照


# 実践編
ではここからは実際に Allzpark を使用するにはどうしたらよいかを解説していく。本稿執筆時点で、allzparkについて日本語での解説記事はみあたらず、公式ドキュメントも導入については詳細に書かれていない。だが安心していただきたい、そのまま流用可能なテンプレートを githubにおいておくので適宜参照・活用してほしい。[zipでDL](https://github.com/yamahigashi/QiitaMayaAdventCalendar2022/archive/refs/heads/main.zip)

サンプルを解凍もしくは git clone してくるとこのような構造になっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17220/b895becf-1967-6d7e-c7f4-d3a0cc1be8ea.png)
***/bin*** 以下にはランチャ自体の起動にかかわるものを配置する
***/rez-packages*** 以下には rez の解釈する packageを配置する
***/scripts*** 以下にもランチャの起動や初期化にまつわるものを配置している

## サンプルの使用方法
`/bin/allzpark.bat` をダブルクリックし起動する。初回起動時には必要なファイルのDLを行うため時間がかかる。しばらく経つとランチャが起動し以下のようなウィンドが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17220/e3f0eae6-718d-d7f0-41be-8083d5426c07.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17220/24aab9be-7a62-16a1-bf4d-36563144d566.png)
左上のこの部分よりプロジェクトの切り替え、プロジェクトのバージョンの切り替えが行える

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17220/b585b167-26a5-ce1e-c5bd-a297c5d14b24.png)
アプリケーション欄右クリメニューからアプリの起動が行える


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17220/3092b4a1-47d3-4971-e888-f766e62f0df2.png)
上部のアイコンから右サイドパネルの表示内容を切り替えられる。図中で選択中の小包パネルからは、選択中のアプリケーションが依存するパッケージのリストが表示される。

## パッケージの構成について
ランチャ自体の動作は取り立てて特別なところはないので中身についてみていこう。ランチャを起動した画面には **アプリケーション** がならび、それぞれのアプリケーションは依存するパッケージがある。この階層構造はどのようにつくられているだろう？

先に述べた `rez-packages` フォルダ以下には![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17220/7c5d1f07-c6a4-5732-74d4-3c712945d4d8.png) 
このようなフォルダがさらに配置されている。rez を起動する際、「どのフォルダのどれをパッケージと見做すか」ということを伝えてやる必要がある。これには環境変数
```bat
set REZ_CONFIG_FILE=%CD%\rezconfig.py
``` 
を設定してやり、その `rezconfig.py` 内で `packages_path` を定義してやればよい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17220/73fc2e94-d73e-7a20-e83d-17462ee75e75.png)
サンプルでは
```python
package_files = list(base.rglob("package.py"))
candidates = set([x.parent.parent.parent.as_posix() for x in package_files])
```
として `rez-packages` 以下の 「パッケージを格納しているフォルダ」を列挙している。これで **Rez** にパッケージを渡すことができた。ここからようやく ***allzpark*** の話になる。allzpark へも同様環境変数を通じて挙動をしらせてやる。
```bat
set ALLZPARK_CONFIG_FILE=%CD%\allzparkconfig.py
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17220/7d879cce-a62f-6431-b465-01e680db4b63.png)
`allzparkconfig.py` では、数ある *rezパッケージ* の中からどれを ***プロジェクト***（allzpark内の用語では *profile* ) として扱うか、***アプリケーション*** として扱うかについての挙動を設定している。
それぞれ、`def profiles()` や `def applications_from_package()` が該当する。このあたりの挙動はドキュメントに書かれていないため、詳細はソースにあたる必要があるのだが、特に変更する必要がないのであればこのサンプルをそのまま使っていただいてOK。

rezパッケージをどのように配置するか、allzparkに組み上げるべきかというのは正解がない。環境に応じ適宜アレンジされたい。筆者の環境ではこのように配置するのが都合がよかった。つまり閉じた環境ではなく複数社、複数プロジェクトで共通の基盤としての使用に耐える構成にした。



## 配布について
ではこのallzparkをあなたのシステム、あるいはユーザさんの環境に届けるにはどのようにしたら良いだろう？
 - インストーラを作成する
 - すべて固めて zip で配布する
 - VCSレポジトリ（git や perforce など）に含める

筆者はVCSに含める運用を行っている。ツール類の更新をどのようにするべきかというのは環境によるところが大きい。起動時の更新チェックや、ファイルの自動更新といった機能をランチャに盛り込むこともできる。必要に応じ改善していっていただきたい。

直接関係するわけではないが配布を支援するようなツールを、rezの機能を用いて作成し [scripts/build.py](https://github.com/yamahigashi/QiitaMayaAdventCalendar2022/blob/main/scripts/build.py)  に配置している。このスクリプトでは、特定の profile と依存するパッケージのみを抽出し zip の作成を行える。特定プロジェクト用の zip を作成する場合に使用できる。スクリプトからどのように依存をたどるのかという好例になっているので興味のある方はご覧いただきたい。

## サンプルファイルで利用するソフトウェアのバージョンについて
Python は 3.9系を使用している。3.10以降とそれ以前でシステム情報の取得形式に差があるためallzpark / rez で対応が必要なのだが、（筆者）が未着手のためだ。また、allzpark は 1.2.183を使用している。これ以降のバージョンでは特定条件下でアイコンの表示に不具合があるためだ。今回サンプル用の環境の構築を行っている際気づいた。`TODO(yamahigashi): fix later`


# おわりに
駆け足に紹介したがいかがだったろうか。ここに解説していない便利なあれやこれやもあるのだが、また機会があれば続編をたてる。必要なものはサンプルに投げ込んであるので（ちょっとしたおまけも入っているよ）気になるところがあればサンプルを動かしてみていただきたい。この記事が皆様のお役に立てば幸いだ。ごきげんよう。