2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

もうbuild.gradle.ktsに振り回されたくない!タスク実行順編

Last updated at Posted at 2021-07-06

文献がない(少ない)!

build.gradle(not Kotlin)しかない(検索しても)!

僕がやりたいのはprintlnじゃない(公式ガイドに対する心の叫び!)!!

※結論は一番下ですので、お急ぎの方は一番下までスクロールしてください。

やりたいこと

私のいる現場のMyBatis Generator周りのビルド手順に
「あれして」「これして」「gradleコマンドを打って」「最後にこれ」
と書かれていたのでなんとかしたかった。

具体的には

  • 特定のフォルダの中身を全部削除して
  • MyBatis Generatorで自動生成したコードだけをJarに固めて
  • GitにCommitできる場所に出す

環境

  • Gradle 6.8.1
  • Kotlin 1.5.20
  • MyBatis Generator 1.4.0

状況整理

MyBatis Generatorの自動生成コードを作って固めるにあたり、実行しなければいけないのは以下です。

  • mbGenerator(自作タスク。※コマンド名には個人差があります、詳しくはMyBatis Generatorで検索)
  • build

加えて、GitにCommitするにあたり、古いコードは消す必要があります。

  • clean
  • cleanDirs(自作タスク。Commit用ディレクトリ・自動生成コードを削除)
build.gradle.kts
tasks.register("cleanDirs", Delete::class) {
    delete(fileTree("削除したいJarのパス").matching { include("*.jar") }
    delete(fileTree("削除したい自動生成コードのパス").matching { include("*.kt") }
    mustRunAfter("clean") //※後述A
}

最後に、build配下に自動生成されたJarをGitにCommitできるパスに持ってくる必要があります。

  • copyJar(自作タスク。上述)
build.gradle.kts
tasks.register("copyJar", Copy::class) {
    from("build/libs")
    include("*.jar")
    into("generated/libs")
    mustRunAfter("build") //※後述A
}

やりたいことを一気に実行してくれるタスクを作る

  • generatedJar
build.gradle.kts
tasks.register("generatedJar") {
    dependsOn(tasks.named("clean"))
    dependsOn(tasks.named("cleanDirs"))
    dependsOn(tasks.named("mbGenerator"))
    dependsOn(tasks.named("build"))
    dependsOn(tasks.named("copyJar"))

…Jarができない。
できるときもある。
・・・?

実は
「dependsOnは順番が固定されない」

これはぐぐると色々出てきます。今回はこれがテーマです。

順番を指定しよう

ボツ案1 doFirst, doLast

doFirst, doLastなるものがあるらしい

(動きません)build.gradle.kts
tasks.register("generatedJar") {
    doFirst {
        dependsOn(tasks.named("clean"))
        dependsOn(tasks.named("cleanDirs"))
    }
    dependsOn(tasks.named("mbGenerator"))
    doLast {
        dependsOn(tasks.named("build"))
        dependsOn(tasks.named("copyJar"))
    }
}

なぜ動かないか

それは「依存の"定義を先に"しただけ」だから。先に実行するとは言ってない。

たしかに

ボツ案2 generatedJarの中でmustRunAfter(後述A)

順番を指定してくれるmustRunAfterを使ってみます。
上述の通り、 cleanDirscopyJar にはタスク定義の中にmustRunAfterを書いたので、その間を繋いでみます

(微妙に動きません※後述B)build.gradle.kts
tasks.register("generatedJar") {
    dependsOn(tasks.named("clean"))
    dependsOn(tasks.named("cleanDirs")) // mustRunAfterと一緒に書かないと実行してくれません
    dependsOn(tasks.named("mbGenerator")) // mustRunAfterと一緒に書かないと実行してくれません
    dependsOn(tasks.named("build"))
        .mustRunAfter("mbGenerator")
        .mustRunAfter("cleaDirs")
    dependsOn(tasks.named("copyJar"))
}

一応書いたものの順番は守ってくれるようになりました。
ただ、mustRunAfterの部分だけ逆順になってるのはしんどい。。

あと、※後述B、と書いていますが
build より先に mbGenerator を実行すると言ったが、"コンパイルより先とは言ってない"」
という地獄の状況になっています。

最終形(後述B)

1つ1つのタスクに、個別にmustRunAfterを付けていきましょう。これで順番が1つずつ定まります。

そして後述Bのポイントですが、 build ではなく compileKotlin の前に mbGenerator が実行されるようにしてください。

build.gradle.kts
tasks.register("cleanDirs"), Delete::class) {
    ..
    mustRunAfter("clean")
}

tasks.named("mbGenerator") { mustRunAfter("cleanDirs") }

tasks.named("compileKotlin") { mustRunAfter("mbGenerator") } // 後述Bのポイント!


tasks.register("copyJar"), Copy::class) {
    ..
    mustRunAfter("build")
}

tasks.register("generatedJar") {
    dependsOn(tasks.named("clean"))
    dependsOn(tasks.named("cleanDirs"))
    dependsOn(tasks.named("mbGenerator"))
    dependsOn(tasks.named("build"))
    dependsOn(tasks.named("copyJar"))
}

ようやくできました。めでたい

(おまけ)実行されるタスク順の確認方法

-mをつけたらドライランができます。これで確認してください。
※上述の通り順番が変わることがあるので、何度か実行してみてください。

gradle generatedJar -m
2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?