pkgboundariesの紹介
aereal.icon 自己紹介
株式会社Classi
開発支援部 システムプラットフォーム領域
業務で使ったり使わなかったりするライブラリ・ツールをあれこれ作るのが趣味です
今日のおはなし
健全な依存グラフを保つことの大切さと難しさ
vetについて
pkgboundariesの紹介
健全な依存グラフと私たち
ソフトウェアアーキテクチャは依存グラフをどう規定するかと言ってもよいと言われている (要出典) 徹底したい
できればツールに指摘させて、人間が指摘せずに済むようにしたい
Goと静的解析とエコシステム
vet
golangci-lintプラグイン
※golangci-lintからgo vetを実行できるので、二項対立するものではないが便宜上併記
vetツール
これを読めば十分で、以下はかいつまんだ説明です
go vet -vettool=/path/to/tool ./... で独自の解析ツールを実装、実行させられる
vetツールを実装するための情報
tenntennさんに足を向けられません ありがとうございます
analysisパッケージを使った実践的なコードがたくさん集まっている
pkgboundariesの紹介
package boundariesというつもりで呼んで・読んでいます
パッケージのまとまりをレイヤと表現し、依存を許可・禁止するレイヤを定義する
違反したimportを発見報告してくれるvetツール
設定 (1/2)
code:config.json
"Layers": [
{
"Name": "App",
"PackageNames": [
"github.com/aereal/a" // Appレイヤに属するパッケージ名
]
},
{
"Name": "Encoding",
"PackageNamePatterns": [
"^encoding/" // 正規表現でパッケージを指定することもできる
]
}
]
設定 (2/2)
code:config.json
"Rules": [
{
"Layer": "App",
"Allowed": [
"Errors" // AppはErrorsに依存しても良い
],
"Denied": [
"Print",
"Encoding" // ただしAppはPrint, Encodingに依存してはいけない
]
}
]
pkgboundariesの紹介: コード例
code:github.com/aereal/a.go
package a
import (
_ "encoding/base64" // want "encoding/base64" cannot be imported by App
_ "encoding/json" // want "encoding/json" cannot be imported by App
_ "errors" // OK
_ "fmt" // want "fmt" cannot be imported by App
)
おまけ: 先行事例
まさにそのものなものを昨日見つけた(……)
pkgboundariesの優位性
外部パッケージを含めて管理できる
pkgboundariesの劣っている点
設定を外部ファイルで渡さないといけない
おまけ: golangci-lintプラグイン対応
意外と手間取っているのでPRもらえると喜びます
おまけ: reviewdogとGitHub Actionsで指摘を自動化
go vetの出力にデフォルトで対応しているので -vettool=$(which pkgboundaries) した結果を渡してあげるだけでOK
完、そして終
静的解析が好きなので静的解析メイトを募集しています