LoginSignup
3
3

More than 5 years have passed since last update.

gradle の FindBugs プラグインで progress 出力を無効化する

Last updated at Posted at 2016-04-04

とあるプロジェクトで、 gradle で findbugs task を実行したときに

Pass 1: Analyzing classes (538 / 552) - 97% complete
Pass 1: Analyzing classes (539 / 552) - 97% complete

みたいな内容がブワーッと出力されて、大事なログが埋もれてしまうようになってしまった。

必ずしも (どのようなプロジェクトでも) おきるわけではなくって、

  • gradle task を parallel 実行している (org.gradle.parallel=true)
    • しかも並列度が高い場合?
  • FindBugs の実行対象が多い

場合に再現するようである。

これを、根本治療が難しかったので、ちょっと hack をしてログに出力されないようにした、というお話。

原因

  • gradle (現時点で 2.12) で parallel processing を有効にしている場合、 標準出力を capture する機構 (logging.captureStandardOutput()) がうまくいかない (ことがある?) GRADLE-3000
  • gradle の FindBugs plugin は、実行時オプションとして -progressつけている
    • Pass 1: Analyzing classes みたいに出力しているのは progress option の結果
    • 上記の stdout capturing がうまく働いた場合、この progress の出力も capture されて log には出力されないはず

対処

GRADLE-3000 が直れば一番いいんだけど、一年以上対応される様子もなく、簡単に直す方法も思いつかなかった。ので、とりあえず FindBugs にわたすオプションから -progress を削除することで対処した。

ざっくりいうと、デフォルトの FindBugs plugin (org.gradle.api.plugins.quality.FindBugsPlugin) を継承して -progress を渡さない plugin をつくり、それを使用する、ということ。

具体的には、プロジェクトに
buildSrc/src/main/groovy/FindBugsWithoutProgressPlugin.groovy という名前で以下のファイルをおいておく。

// groovy は package scope の関数等にアクセスできるみたいだけど一応 package を揃えとく
package org.gradle.api.plugins.quality

import org.gradle.api.JavaVersion
import org.gradle.api.logging.LogLevel
import org.gradle.api.plugins.quality.internal.findbugs.*

class FindBugsWithoutProgressPlugin extends FindBugsPlugin {
    // 本来必要ないけど configureTaskDefaults() で extension 使っているので用意しておく
    private FindBugsExtension extension

    @Override
    protected Class<FindBugs> getTaskType() {
        return FindBugsWithoutProgress
    }

    // ここで extension 埋めておく
    @Override
    protected CodeQualityExtension createExtension() {
        extension = super.createExtension() as FindBugsExtension
        return extension
    }
}

class FindBugsWithoutProgress extends FindBugs {
    // FindBugs#run() のほぼそのままのコピペ
    @Override
    void run() {
        new FindBugsClasspathValidator(JavaVersion.current()).validateClasspath(getFindbugsClasspath().files*.name)

        // FindBugs の options から -progress を除去する
        FindBugsSpec spec = generateSpec()
        List<String> args = spec.getArguments()
        args.remove(args.indexOf("-progress"))

        FindBugsWorkerManager manager = new FindBugsWorkerManager()

        logging.captureStandardOutput(LogLevel.DEBUG)
        logging.captureStandardError(LogLevel.DEBUG)

        FindBugsResult result = manager.runWorker(getProject().getProjectDir(), workerProcessBuilderFactory, getFindbugsClasspath(), spec)
        evaluateResult(result);
    }
}

あとは

apply plugin: "findbugs"

のように plugin を読み込んでいるところを

apply plugin: FindBugsWithoutProgressPlugin

のように変えればよい。 (findbugs plugin の設定部分はそのままでよい)

3
3
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
3
3