0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Gradle】マルチモジュールプロジェクトのversion catalog移行・運用ルール制定を行った話

Last updated at Posted at 2024-07-27

Dependabotversion catalog対応していたことを今更ながら知ったため、社内のマルチモジュールSpringBootプロジェクトをversion catalog移行しました。

この記事では、移行に当たって意識したことや制定したルール、得られたメリットについて書きます。

移行で得られたメリット

当該プロジェクトでは基本的にSpring等のBOMに合わせたバージョンの依存を利用しており、移行で記述量が減らせる等のメリットはそれ程享受できなかった感が有ります。
ただ、バージョンを書く個所が一元化されたことによって、依存の更新作業を行う上で必要とされる前提知識を減らすことができ、作業ミスの発生確率もほぼ0にできました。
その意味で、完全な一元管理が可能というのはやはりメリットが大きいと感じます。

また、Dependabotが同じ依存に対しても複数のPRを送ってくる問題も解決されました1

移行に当たって定めたルール

今後の運用において混乱が生じないよう定めた一応のルールに関しても書きます。
ただ、これに関しては走り出したばかりであるため、今後変動が有るかもしれません。

基本方針としては、以下を重視しました。

  • 移行の労力を小さくする
  • 追記が楽なようにする
  • メンテナンスが楽なようにする

version catalogへの移行基準

少し触れましたが、この当該プロジェクトでは基本的にSpring等のBOMに合わせたバージョンの依存を利用しています。
このため、全ての依存をversion catalogへ移行した場合、むしろ以下のようなデメリットが生じます。

  • 移行に当たっての書き換え量が多くなる
  • 依存を追加する場合version catalogdependencies両方の書き替えが生じる
    • これは移行前より記述量が多い
    • 削除時も両方から削除のが必要になる
  • ルートのversion catalogにあらゆる依存を詰め込んで見通しを悪くするか、ファイル分割で状況を複雑化させるかの択が生じる

そこで、移行対象はバージョンを明示的に指定しているものだけとし、以下のようにバージョン指定が省略されていれば移行対象外としました。

バージョン省略された依存の例
implementation("org.springframework.boot:spring-boot-starter-web")

version catalogの記述ルール

[versions]セクション

複数の依存で利用するか、build.gradleにおいて定数的に利用したいような場合を除き、バージョンは直接書く方針としました。
これは日々の追記をコピペで済ませやすくするための方針です(後述)。

[plugins]セクション

個々の定義は、基本的に以下の形式で書く方針としました。

[plugins]
spring-boot = { id = "org.springframework.boot", version = "3.3.2" }

これはGradle Pluginsからのコピペをやりやすくするための方針です。
細かいことを言うと、形が似ているため、Groobyタブからコピペするのがお勧めです。

Groovyタブに表示される例
plugins {
  id "org.springframework.boot" version "3.3.2"
}

試した限り以下のようなワンライナー形式でも書けるようでしたが、こちらは採用しませんでした。

[plugins]
spring-boot = "org.springframework.boot:3.3.2"

[libraries]セクション

個々の定義は、基本的に以下の形式で書く方針としました。
この形式であってもDependabotは正常稼働してくれることを確認しています。

[libraries]
spring-boot-starter-web = "org.springframework.boot:spring-boot-starter-web:3.3.2"

これはMaven Centralからのコピペをやりやすくするための方針です。
細かいことを言うと、形が似ているため、Gradle(Kotlin)がコピペしやすかったです。

Gradle(Kotlin)タブに表示される例
implementation("org.springframework.boot:spring-boot-starter-web:3.3.2")

以下の形式でも書けます(というかこちらの方が一般的?)が、こちらは採用しませんでした。

[libraries]
spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web", version = "3.3.2" }

その他

移行対象となるような内容は特別な事情を持っている場合が多く、付随するコメントも有りました。
それらのコメントに関しては、分散している方が混乱を招きそうだったため、同時にversion catalog側へ移行することとしました。

また、以下の理由から、記述ルールは必要に応じて無視してOKという方針にしました。

  • 日常的に頻出する操作が楽な方針にするとどうしても例外が出る
    • 特に[libraries]から[versions]に定義されたバージョンを参照する場合
  • 方針的にversion catalogはそれ程肥大せず、ロジックも無いため、多少のブレは許容できる

ハマったポイント

最後におまけとして、移行時ハマったポイントを幾つか紹介します。

subprojects内でlibsに定義された内容が参照できない

以下に報告されている問題です。

これは一旦トップレベル変数に取得しておくことで解決できました。

+ val foo = libs.foo.get()

  subprojects {
      dependencies {
-         implementation(libs.foo)
+         implementation(foo)
      }
  }

社内GitHub Packagesの依存がDependabotに検出されない

プロジェクトのrepositories設定によって生じた問題です。
こちらは個別に記事にしています。

  1. 既にグループ化してPR発行できるようなので、これはDependabot設定が悪かっただけ感は有りますが……。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?