gradleで依存するライブラリを書けば、自動的にその依存関係を解消してくれて便利なのですが、意図しないライブラリに依存してしまったり、意図せず利用ライブラリのバージョンが上がってしまったりという問題が発生してしまう場合もあります。
以下のように、実行時の依存関係をツリー表示させて、それを人力でチェックする……というのはきびしいですね。
./gradlew :app:dependencies --configuration releaseRuntimeClasspath
dependency-guard
dropboxがdependency-guardというgradle pluginを公開しており、これを使うことで簡単に依存関係の変化をチェックすることができます。
build.gradle.ktsのpluginsセクションにdependency-guardを記述し
plugins {
id("com.dropbox.dependency-guard") version "0.5.0"
}
以下のようにチェックする構成を指定します。
Javaプロジェクト・ライブラリの場合 runtimeClasspath
Androidアプリ・ライブラリの場合 releaseRuntimeClasspath
が対象になると思います。
Build Variantsを設定している場合はそれに合わせて構成名を変更します。
dependencyGuard {
configuration("releaseRuntimeClasspath")
}
こうすることで dependencyGuard / dependencyGuardBaseline のタスクが作られます。
いずれかのタスクを実行すると、dependenciesディレクトリと、その中にテキストファイルが作成されます。
このテキストファイルには依存ライブラリの一覧が辞書順にリストアップされています。
このファイルはVCSにコミットしてバージョン管理しておきます。
dependencyGuardはこのファイルと現在の依存関係の変化を検出し、変化があればエラーとなります。(ファイルがなければ作成されます)
例えば、androidx.activityのバージョンが1.7.0から1.8.0に更新されると以下のようなエラーとなります。
Dependencies Changed in :app for configuration releaseRuntimeClasspath
- androidx.activity:activity:1.7.0
+ androidx.activity:activity:1.8.0
存在しない依存関係が増えた場合、
> Dependencies Changed in :app for configuration releaseRuntimeClasspath
+ androidx.activity:activity:1.8.0
既存の依存関係が消えた場合、
> Dependencies Changed in :app for configuration releaseRuntimeClasspath
- hoge.fuga.piyo:piyo:1.0.0
いずれの場合も変化ががあるとエラーとなりますので、CIで実行するようにしておくと、意図しない変化が含まれてしまうのを防ぐことができます。
dependencyGuardBaselineを実行すると、ファイルが更新されます。
意図した依存関係の変化であれば、dependencyGuardBaselineを実行し、これをコミットに含めます。
これで、依存関係の変化を履歴として残すことができ、ライブラリの場合は利用者に依存ライブラリの一覧を示すことも容易にできますね。
特定の依存関係の混入をエラーとする
このプラグインにはいくつかのオプションが用意されています。そのうちのallowedFilter
を使うことで、特定の依存関係の混入を一律エラーにすることができます
allowedFilterにはラムダを渡します、このラムダにはandroidx.activity:activity:1.8.0
の様な、依存するライブラリ名が渡されますので、禁止したいライブラリだった場合にfalseを返すようにします。
以下の例では、"junit"を含む名前のライブラリが含まれていたらエラーとしています。
dependencyGuard {
configuration("releaseRuntimeClasspath") {
allowedFilter = { dependencyName ->
!it.contains("junit")
}
}
}
テスト用やデバッグ用のライブラリがリリースビルドに含まれてしまうのは良くないですよね。他にもビジネス的な観点や、ライブラリの方針的に、特定のライブラリに依存したくない場合というのは、そこそこあるのではないかと思います。
そういった混入しては困るライブラリがある場合は、このようなルールを書いておき、CIでチェックすることで、意図せず依存させてしまうという問題を防ぐことができます。