Septeni Engineer's Blog

セプテーニエンジニアが綴る技術ブログ

gradle + scalariformでbuild時に自動フォーマット

はじめに

お久しぶりです、加藤です。
そろそろ夏の訪れを感じる頃かと思います。 最近、業務でscalariformを導入する機会があったため、その手順を書いていこうかなと思います。 sbt + scalariformも導入しましたが、こちらは参考記事がたくさんあるので割愛します。

手順

  • プロジェクト内のbuild.gradleに追記
  • フォーマッターの設定ファイル(scalariform.properties)を作成

では、実際に記述していきます。

build.gradle

buildscript {
    dependencies {
        classpath "org.scalariform:scalariform_2.11:0.1.8"
    }
}

compile "org.scalariform:scalariform_2.11:0.1.8"

import scala.None$
import scalariform.formatter.preferences.PreferencesImporterExporter$
import scalariform.formatter.ScalaFormatter$
import scalariform.ScalaVersions

task format {
    // 設定ファイルのパス
    def prefsFile = "$rootDir/reader2/scalariform.properties"
    def prefs = PreferencesImporterExporter$.newInstance().loadPreferences(prefsFile)

    project.fileTree(project.projectDir).include("**/*.scala").each { File f ->
        String contents = f.text
        def formattedContents = ScalaFormatter$.newInstance().format(contents, prefs, None$.apply("\n"), 0, ScalaVersions.Scala_2_11().toString())
        if (!formattedContents.equals(contents)) {
            println("Formatted $f")
            f.write(formattedContents, "UTF-8")
        }
    }
}

ここでいくつか注意が必要です。

  • task formattask format <<としてしまうとbuild時に自動フォーマットが適用されません。
  • 設定ファイルのパスは、Android Studioの場合は相対パスで問題ありませんが、IntelliJの場合はエラーになってしまうので絶対パスを指定しました。

上記以外にも、まだバージョンによる落とし穴などが潜んでいるかもしれませんね。

scalariform.properties

こちらは参考までに載せておきます。 好みが分かれる部分でもありますし、プロジェクトの規則に合わせて変更するのが良いでしょう。

doubleIndentClassDeclaration=true
placeScaladocAsterisksBeneathSecondAsterisk=true
alignSingleLineCaseStatements=true

おわりに

実際に行ってみると簡単ですね。 ただ、調べてみると案外導入例が少ないみたいです。 プロジェクト内でフォーマットを統一しておくと、レビューの際に余分な差分が発生せずに、本質がより明確になるかと思いますので是非。 また、task format以下は他にも色々な記法があると思うので是非導入してみてください。