Graphviz
Graphviz と言えば、PlantUMLや Doxygenが UML 図などを生成するために内部で使用していることで有名なので、ユーザーが直接使うソフトウェアというイメージは薄いかもしれません。
しかし DOT言語という表記法で簡単なテキストファイルを作ってコマンドを実行するだけで図を生成してくれるので、何かと便利なツールだったりします。
上記は PlantUML と Doxygen で生成された図の公式サンプルです。こういう複雑で綺麗な図を作るのは大変ですが、単純な ○→○ だけで表現できる関係の図なら簡単に作ることができます。
ハローワールド的な例
例えば下図の左のように「1」と「2」の関係を記しただけの簡単なテキストが、自動的に右の図に変換されます。
2本の線が重ならないように自動的に避けて配置されていますが、このように配置や大きさもお任せできるので、手作業を排除した完全自動化を実現することができます。
公式ドキュメント
https://www.graphviz.org/documentation/
使用例: 自作RPMの依存関係を可視化する
RPM パッケージには「どのパッケージに依存するか」がメタ情報として定義されています。yum などのパッケージマネージャはこれを参照して、依存パッケージを自動的にインストールしてくれます。
しかし自作パッケージが増えてくると、どれがどれに依存しているかを忘れてしまいがちです。もちろん個別にコマンドで確認することはできるのですが、全パッケージの依存関係図を自動生成できればと思って試してみました。
単純な ○→○だけの図でも、依存関係を可視化するという目的には十分です。
RPMパッケージのSPECファイル
RPM パッケージを自作する場合は SPEC ファイルというテキストファイルにメタ情報を記述して、ターゲットにインストールするプログラムやファイルと一緒にビルドして配布します。
依存パッケージは以下のようにRequires
で始まる行で定義します。
Requires: nginx >= 1.14
Requires: myapp-lib >= 0.1.0
Requires(post): jq >= 1.5
つまりスクリプトを作って SPEC ファイルからRequires
で始まる行のパッケージ名を抽出するだけで、DOT 言語で表記したファイルを作ることができます。
DOTファイル生成スクリプト
言語は何でもいいのですが、bash スクリプトならこんなに簡単になります。
#!/bin/bash# *****************************************************************************# 指定ディレクトリ内の全SPECファイルから「Requires」で始まる行に定義された依存# パッケージ名を抽出し、依存関係をDOT言語の表記で出力する。## $1 SPECファイルがあるディレクトリfunction print_digraph(){local spec_file=local required_package=echo"digraph {"cd"${1}"for spec_file in$(ls-1*.spec)do
grep"^\s*Requires.*:""${spec_file}" | awk'{print $2}' |
while IFS=read required_package
do# 依存元パッケージ名はSPECファイルから拡張子を除去した名前で、# ' "依存元パッケージ名" -> "依存先パッケージ名"' を出力する。echo" \"${spec_file%.*}\" -> \"${required_package}\""done
done
echo"}"}################################################################################ $1 SPECファイルがあるディレクトリ。# $2 出力する画像ファイル。# 全SPECファイルからDOTファイルを生成して、DOTファイルから図を生成する。_dot=$(print_digraph "${1}")
dot -T png -o"${2}"<<<"${_dot}"# 生成された画像ファイルを表示して終了する。
eog "${2}"&
exit 0
実行結果
SPEC ファイルを 10個作成してスクリプトを実行したら、下図の画像が一瞬で生成されました。
関数内で生成した DOT 言語のテキストは以下のとおりです。
digraph {
"myanim-lib" -> "mybase-lib"
"myapp-lib" -> "myftp-lib"
"myapp-lib" -> "myhttp-lib"
"myapp-lib" -> "myfile-lib"
"myapp-lib" -> "myui-lib"
"myapp" -> "nginx"
"myapp" -> "myapp-lib"
"myapp" -> "jq"
"myfile-lib" -> "mybase-lib"
"myftp-lib" -> "mynetwork-lib"
"myhttp-lib" -> "mynetwork-lib"
"mynetwork-lib" -> "mybase-lib"
"mynetwork-lib" -> "NetworkManager"
"myui-lib" -> "mybase-lib"
"myui-lib" -> "myvideo-lib"
"myui-lib" -> "myanim-lib"
"myvideo-lib" -> "mybase-lib"
"myvideo-lib" -> "ffmpeg"
}
あとがき
Graphviz が超優秀なソフトウェアなので、ご覧のとおりの簡単なスクリプトを作っただけで可視化の自動化ができちゃいました。工数対効果が大変高くてお得です。