kumak1’s blog

kumak1のイラストや技術ログ

Unity の Assembly Definition の依存関係を PlantUML で出力する雑スクリプト書いた

Unity - Manual: Assembly definitions 使ってますか?

qiita.com

上記の記事のような完全に理解したツワモノのおかげで、わたしも色々恩恵をいただいております。 肥大化した自作コードを分割できたり、エディタービルド時間を削減できたりして便利ですね。

f:id:kumak1:20200913234032p:plain

コードで上で縛るのはもちろん、このように単体の依存関係を目で確認しやすいのも良い所ですね。

ここまでできると「プロジェクト全体など任意のスコープで俯瞰した図をみたい」「Docusaurusなどのドキュメントでも俯瞰図みたい」と欲が深くなったので、指定ディレクトリ配下を検索して PlantUML を出力できるようなスクリプトを書いてみました。

jqyq を利用してるので注意、と、よしなに改変してご自由に利用ください。

#!/usr/bin/env bash

JQ=/usr/local/bin/jq
YQ=/usr/local/bin/yq

TARGET_FILE=\*.asmdef
WORK_DIR=$1
UP_ARROW="-up->"

# オプションがなければカレントディレクトリが処理対象。
# 空白のあるディレクトリ名・ファイル名を考慮してないので注意
if [ -z "${WORK_DIR}" ]; then
  WORK_DIR="."
fi

ITEMS=$(find "${WORK_DIR}" -name "${TARGET_FILE}")
ROOT="\"Assembly-CSharp\""
TEXTS=()

echo "@startuml"
echo "component ${ROOT}"

for ITEM in ${ITEMS}; do
  NAME=$(cat $ITEM | $JQ '.name')

  # コンポーネントを宣言
  echo "component ${NAME}"

  # Assembly-CSharp への依存関係を明示
  if [ $(cat $ITEM | $JQ -r '.autoReferenced') = "true" ]; then
    echo "[${NAME}] ${UP_ARROW} [${ROOT}]"
  fi

  # その他ライブラリへの依存関係をいったん控える
  for GUID in $(cat $ITEM | $JQ -r 'select(.references != null) | .references[]' | sed s/GUID://); do
    TEXTS+=("[${NAME}] ${UP_ARROW} [${GUID}]")
  done
done

# bash 3.2 利用想定なので非常に非効率(ハッシュが使えない・・)
# 利用しているシェルに合わせて、GUID -> Assembly Definition File Name への置換処理をチューニングしましょう
for ((i = 0; i < ${#TEXTS[@]}; i++)) {
  SHOW=false

  for ITEM in ${ITEMS}; do
    NAME=$(cat $ITEM | $JQ '.name')
    GUID=$($YQ read $ITEM.meta 'guid')

    if [ "`echo ${TEXTS[$i]} | grep ${GUID}`" ]; then
      echo ${TEXTS[$i]} | sed s/${GUID}/${NAME}/
      SHOW=true
      break
    fi
  done
  
  if ! "${SHOW}"; then
    echo ${TEXTS[$i]}
  fi
}

echo "@enduml"

これを実行すると PlantUML が標準出力されるので、クリップボードにコピーしてよしなに利用しましょう。 JetBrains IDE 利用者は PlantUML integration - Plugins | JetBrains を使うと scratch で作成できるし、プレビューも画像保存も手軽で良い。

で、実際に私が出力してみたものがこんな感じ。

f:id:kumak1:20200913235612p:plain

どう依存してるかは俯瞰してみれるようになったが、なんだか大変煩雑な図ができあがってしまった。。コードをもっと整理しないとな・・ (図内でGUIDが直接出力されているのは、対象ディレクトリ外に Assembly Definition File があるため。Rewired や Behavior Designer などの asset だ)

なにはともあれ、こういった問題点も可視化できて便利だな?