自作パッケージの依存関係ちゃんと管理してる?静的解析とGraphvizで実現した自作パッケージ依存関係可視化ツール"prelviz"
はじめまして、株式会社アプリボットでバックエンドエンジニアをしている@_kz_devです。普段はスマホゲームのバックエンド開発をしています。
この記事はGo Advent Calender 2023とApplibot Advent Calenderの 23日目の記事です。
この記事は、
- "プロダクトのパッケージの依存関係ちゃんと見たいなあ~",
- "このパッケージ修正するときに、どのパッケージに影響しそうかな~?"
- "依存関係的にアーキテクチャ違反しているパッケージないよね、ちょっと気になるな~?"
などなどの、私が抱いていた気持ちや疑問を解消するために開発した、自作パッケージの依存関係の可視化ツールprelvizについての紹介記事です。
※全てのケースでうまく動作するとは限りませんのでご注意ください!
紹介するツールのリポジトリを以下に載せておきます。
概要
prelvizをgoプロジェクトに対して実行し、Graphvizで画像変換すると以下のような結果を得られます。
長方形がパッケージを表し、長方形間の線がリレーションを表現しています。
線上の"dep"は矢印の向きに存在するパッケージへの依存数を指します。(依存数は、依存先パッケージの構造体や関数の利用種類数です。)
また、設定ファイルを調整すると、それぞれ以下のような結果を得られます。
デフォルト設定時の結果 | NGな依存関係を設定時の結果 |
---|---|
デフォルト設定時の結果 | グルーピングするパッケージを設定時の結果 |
---|---|
デフォルト設定時の結果 | 除外するパッケージを設定時の結果 |
---|---|
"app/util"・"app/domain/entity"を除外している |
デフォルト設定時の結果 | NGな依存関係とグルーピングするパッケージを設定時の結果 |
---|---|
デフォルト設定時の結果 | グルーピングするパッケージと除外するパッケージを設定時の結果 |
---|---|
"app/util"・"app/domain/entity"を除外している |
使い方
1.prelvizをinstallする
go install github.com/kazdevl/prelviz/cmd/prelviz@v1.0.1
2.実行時に引数を指定する
標準実行
prelviz -i {{対象Goプロジェクトのルートパスを指定する}}
DOT言語が標準出力されます
出力ファイルの指定
prelviz -i {{対象Goプロジェクトのルートパスを指定する}} -o {{出力ファイルを指定する}}
"-o"を指定することで、指定したファイルに結果が出力されます。
レイアウトの変更
prelviz -i {{対象Goプロジェクトのルートパスを指定する}} -l {{利用するレイアウトを指定する}}
"-l"を指定することで、Graphvizで利用するレイアウトが変更されます。
※ レイアウトの種類は、以下を参考にしてください。
画像変換
prelviz -i {{対象Goプロジェクトのルートパスを指定する}} | dot -Tpng -o sample.png
dotコマンドを利用することで、画像に変換できます。
※ dotコマンドのオプションは以下を参考にしてください。
3.".prelviz.config.json"を設定する(推奨)
prelvizでは、".prelviz.config.json"を対象プロジェクトのルートパスに設定することで、以下の設定を適用できます。
- NGな依存関係
- "ng_relation"に値を設定する
- "from"と"to"でNGな依存関係を設定する
- NGな依存関係はパッケージ間の線を赤色に表示します。
- パッケージをグルーピングするディレクトリの指定
- "grouping_directory_path"に値を設定する
- 設定したディレクトリ配下に存在するパッケージは一つにまとめられる
- まとめられたパッケージは緑色で表示される
- 除外するパッケージ
- "exclude_package"に値を設定する
- 設定したパッケージに関する情報が省かれる
以下に"prelviz.config.json"の設定例を示します。
{
"ng_relation": [
{
"from": "github.com/kazdevl/sample_project/app/usecase",
"to": ["github.com/kazdevl/sample_project/app/domain"]
}
],
"grouping_directory_path": ["app/domain"],
"exclude_package": [
"github.com/kazdevl/sample_project/app/util",
"github.com/kazdevl/sample_project/app/domain/entity"
]
}
その他、prelvizの詳細な説明は以下のREADME.mdをお読み下さい!
要素技術
静的解析
prelvizでは、各パッケージが依存しているパッケージ一覧や依存数を可視化しています。それらを取得するために、対象パッケージのファイルのASTに存在する、*ast.ImportSpec・*ast.SelectorExprを利用します。
prelvizでの、AST走査処理が気になる方は、以下のコードを参照してください。
Graphviz
パッケージや依存関係の図や線などを、よしなに配置して画像に書き起こすために、Graphvizを採用しました。Graphvizで図や線を作成するには、DOT言語を利用します。
prelvizで、読み込んだパッケージやその依存関係などをDOT言語に書き起こすために、以下のライブラリを利用しました。
prelvizでの、上記のライブラリを利用した実装が気になる方は、以下のコードを参照してください。
終わりに
本記事では、独自パッケージの依存関係情報を可視化するprelvizについて紹介しました!
今後、読者様がGoのプロダクトで、自作パッケージの依存関係をしっかりと管理したい!という時に、本ツールが助けになれば幸いです。
prelvizは作り始めたばかりであり、考慮できていないところもたくさんあると思います。バグ報告や機能改善要望などは是非GitHubで気軽にissueを投げてください。starも頂ければ大きな活力になります。
Go Advent Calender 2023の24日目はさんの@mylifewithviolinさんの記事です。そして、Applibot Advent Calenderの 24日目は @Sigsiguma
さんの記事です。
お楽しみに!
Discussion