groovyとcheckstyleによるプロジェクト固有のコーディングルールのチェック手順
Javaの静的検査ツールcheckstyleを使って、
プロジェクト独自のコーディングルールをチェックする手順をまとめます。
ここでは、手軽にルールを追加できるようにgroovyでルールを実装します。
checkstyle
http://checkstyle.sourceforge.net/
対象プロジェクトの作成
最初にgradle init
で対象プロジェクトを作成します。
$ mkdir checkstylesample && cd $_
$ gradle init
$ mkdir -p src/main/java
gradleの設定とチェック対象の処理を実装を行います。
build.gradle
apply plugin: 'java'
src/main/java/Application.java
public class Application {
public static void main(String[] args) {
System.out.println("hello check! to stdout");
System.err.println("hello check! to stderr");
}
}
以下のように、問題なくビルドできることを確認しておきます。
$ gradle build
buildSrcへの独自ルールの実装
buildSrc配下に独自ルールを実装するので、
buildSrc配下のディレクトリを準備します。
$ mkdir buildSrc
$ mkdir -p buildSrc/src/main/groovy
buildSrc配下でcheckstyleとgroovyが使えるようにgradleを設定します。
buildSrc/build.gradle
apply plugin: 'groovy'
repositories {
mavenCentral()
}
dependencies {
compile group: 'com.puppycrawl.tools', name: 'checkstyle', version: '8.12'
compile group: 'org.codehaus.groovy', name: 'groovy-all', version: GroovySystem.getVersion()
}
次にgroovyでチェック処理を実装します。
ここではSystem.out.println
をデバッグ用の記述と判断して、
削除するように促すルールを書いてみます。
buildSrc/src/main/groovy/DebugPrintCheck.groovy
import com.puppycrawl.tools.checkstyle.api.AbstractCheck
import com.puppycrawl.tools.checkstyle.api.DetailAST
import com.puppycrawl.tools.checkstyle.api.TokenTypes
class DebugPrintCheck extends AbstractCheck {
@Override
int[] getDefaultTokens() {
return this.getRequiredTokens()
}
@Override
int[] getAcceptableTokens() {
return this.getRequiredTokens()
}
@Override
int[] getRequiredTokens() {
return [TokenTypes.METHOD_CALL]
}
@Override
void visitToken(DetailAST ast) {
if ("System" == ast.getFirstChild()?.getFirstChild()?.getFirstChild()?.getText()
&& "out" == ast.getFirstChild()?.getFirstChild()?.getFirstChild()?.getNextSibling()?.getText()
&& "println" == ast.getFirstChild()?.getFirstChild()?.getNextSibling()?.getText()) {
log(ast, "デバッグ用のSystem.out.printlnは削除しておくべき");
}
}
}
チェック処理の書き方はこの辺りを参考にしてください。
checkstyle用の独自チェックを実装してみた | takemikami’s note
http://takemikami.com/2018/07/28/checkstyle.html
Groovyのセーフナビゲーションを使うと、
ツリー構造をたどって確認する処理も、だいぶ楽に記載できます。
9.Nullセーフ | Apache Groovyチュートリアル
https://koji-k.github.io/groovy-tutorial/null-safe/index.html
対象プロジェクトへのルール適用
次に、作成したルールを対象プロジェクトに適用します。
checkstyleの設定ファイルを作成し、
gradleの設定にcheckstyleを追加します。
build.gradle
apply plugin: 'java'
apply plugin: 'checkstyle'
repositories {
mavenCentral()
}
dependencies {
checkstyle group: 'com.puppycrawl.tools', name: 'checkstyle', version: '8.11'
checkstyle group: 'org.codehaus.groovy', name: 'groovy-all', version: GroovySystem.getVersion()
checkstyle files('buildSrc/build/libs/buildSrc.jar')
}
config/checkstyle/checkstyle.xml
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="TreeWalker">
<module name="DebugPrintCheck" />
</module>
</module>
以下のように、チェック処理を実行し、検出できることを確認します。
$ gradle check
> Task :checkstyleMain FAILED
[ant:checkstyle] [ERROR] ※プロジェクトのパス※/src/main/java/Application.java:3:23: デバッグ用のSystem.out.printlnは削除しておくべき [DebugPrint]
FAILURE: Build failed with an exception.
※省略※
IntelliJ IDEAでの実行
最後に、作成したルールをIntelliJ IDEAのInspectionで表示できるようにします。
Preferences → Plugins → Browse Repositoriesを開き、
「Checkstyle-IDEA」を検索し、プラグインをインストールします。
プラグインをインストールした後、
Preferences → Other Settings → Checkstyle
と選ぶと、以下のような画面が表示されます。
「Third-Party Checks」に、buildSrc/build/libs/buildSrc.jar
を追加します。
「Configuration File」に、以下の設定を追加します。
- Description: Project Original
- Use a local Checkstyle file: チェックあり
- File: config/checkstyle/checkstyle.xml
- Store relative to project location: チェックあり
追加後、Activeにチェックを入れておきます。
設定後に、Build → Rebuild Project を実行すると、
Inspectionにエラーが表示されるようになります。
最後に「.idea/checkstyle-idea.xml」ファイルの、
thirdparty-classpathの箇所を、以下のように変更しておくことをお勧めします。
# gradleでbuildSrc.jarをビルドする必要がなくなるので。
.idea/checkstyle-idea.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CheckStyle-IDEA">
<option name="configuration">
<map>
<entry key="active-configuration" value="PROJECT_RELATIVE:$PROJECT_DIR$/config/checkstyle/checkstyle.xml:Project Original" />
<entry key="checkstyle-version" value="8.12" />
<entry key="copy-libs" value="false" />
<entry key="location-0" value="BUNDLED:(bundled):Sun Checks" />
<entry key="location-1" value="BUNDLED:(bundled):Google Checks" />
<entry key="location-2" value="PROJECT_RELATIVE:$PROJECT_DIR$/config/checkstyle/checkstyle.xml:Project Original" />
<entry key="scan-before-checkin" value="false" />
<entry key="scanscope" value="JavaOnly" />
<entry key="suppress-errors" value="true" />
<entry key="thirdparty-classpath" value="$PROJECT_DIR$/buildSrc/out/production/classes" />
</map>
</option>
</component>
</project>
コーディングルールのドキュメントを作成して、
メンバー全員が熟知している状態を維持するのは難しいので。
ルールを記載して機械的にチェックする
という方法を取り入れるとストレスも少なく開発が出来るでしょう。