| ------ |
| Using Custom Developed Checkstyle Checks |
| ------ |
| 2008-02-04 |
| ------ |
| |
| ~~ Licensed to the Apache Software Foundation (ASF) under one |
| ~~ or more contributor license agreements. See the NOTICE file |
| ~~ distributed with this work for additional information |
| ~~ regarding copyright ownership. The ASF licenses this file |
| ~~ to you under the Apache License, Version 2.0 (the |
| ~~ "License"); you may not use this file except in compliance |
| ~~ with the License. You may obtain a copy of the License at |
| ~~ |
| ~~ http://www.apache.org/licenses/LICENSE-2.0 |
| ~~ |
| ~~ Unless required by applicable law or agreed to in writing, |
| ~~ software distributed under the License is distributed on an |
| ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| ~~ KIND, either express or implied. See the License for the |
| ~~ specific language governing permissions and limitations |
| ~~ under the License. |
| |
| ~~ NOTE: For help with the syntax of this file, see: |
| ~~ http://maven.apache.org/doxia/references/apt-format.html |
| |
| |
| Using Custom Developed Checkstyle Checks |
| |
| We will guide you through creating a Maven project that produces a jar file of |
| your custom checks. Then we'll include it in one of your projects by adding it |
| as a dependency to the Checkstyle Plugin. |
| |
| The plugin also provides the ability to define the |
| {{{http://checkstyle.sourceforge.net/config.html#Packages}package names XML document}} |
| required to reference your custom check modules more easily. |
| |
| In this example we will be using the |
| {{{http://checkstyle.sourceforge.net/writingchecks.html#Visitor%20in%20action}example check}} |
| that can be found on the Checkstyle web site. |
| |
| |
| * Structuring your project |
| |
| First we set up the directory structure for the custom ckecks project. It |
| looks like this: |
| |
| +-----+ |
| mycompany-checkstyle-checks |
| |-- pom.xml |
| `-- src |
| `-- main |
| `-- java |
| `-- com |
| `-- mycompany |
| `-- checks |
| |-- packagenames.xml |
| `-- MethodLimitCheck.java |
| +-----+ |
| |
| Now we'll go through each of the three files one at a time. |
| |
| ** <<<pom.xml>>> |
| |
| Not much to say here, except that we add a dependency on Checkstyle. |
| |
| +-----+ |
| <project> |
| <modelVersion>4.0.0</modelVersion> |
| <groupId>com.mycompany</groupId> |
| <artifactId>mycompany-checkstyle-checks</artifactId> |
| <name>MyCompany Checkstyle Checks</name> |
| <version>1.0</version> |
| <dependencies> |
| <dependency> |
| <groupId>checkstyle</groupId> |
| <artifactId>checkstyle</artifactId> |
| <version>${project.version}</version> |
| </dependency> |
| </dependencies> |
| </project> |
| +-----+ |
| |
| ** <<<packagenames.xml>>> |
| |
| This file lets you specify the names of the packages that you want to be able |
| to use. Here we have added <<<com.mycompany.checks>>> to the standard set of |
| Checkstyle packages. That means that you can use your custom checks in the |
| Checkstyle configuration file, without having to specify their package name. |
| |
| +-----+ |
| <?xml version="1.0" encoding="UTF-8"?> |
| |
| <!DOCTYPE checkstyle-packages PUBLIC |
| "-//Puppy Crawl//DTD Package Names 1.0//EN" |
| "http://www.puppycrawl.com/dtds/packages_1_0.dtd"> |
| |
| <checkstyle-packages> |
| <package name="com.mycompany.checks"/> |
| <package name="com.puppycrawl.tools.checkstyle"> |
| <package name="checks"> |
| <package name="blocks"/> |
| <package name="coding"/> |
| <package name="design"/> |
| <package name="duplicates"/> |
| <package name="header"/> |
| <package name="imports"/> |
| <package name="indentation"/> |
| <package name="j2ee"/> |
| <package name="javadoc"/> |
| <package name="metrics"/> |
| <package name="modifier"/> |
| <package name="naming"/> |
| <package name="sizes"/> |
| <package name="whitespace"/> |
| </package> |
| <package name="filters"/> |
| </package> |
| </checkstyle-packages> |
| +-----+ |
| |
| ** <<<MethodLimitCheck.java>>> |
| |
| Here is the example check from the Checkstyle site. It checks that your source |
| files don't have more that 30 methods. |
| |
| +-----+ |
| package com.mycompany.checks; |
| import com.puppycrawl.tools.checkstyle.api.*; |
| |
| public class MethodLimitCheck extends Check |
| { |
| private int max = 30; |
| |
| public int[] getDefaultTokens() |
| { |
| return new int[]{TokenTypes.CLASS_DEF, TokenTypes.INTERFACE_DEF}; |
| } |
| |
| public void visitToken(DetailAST ast) |
| { |
| // find the OBJBLOCK node below the CLASS_DEF/INTERFACE_DEF |
| DetailAST objBlock = ast.findFirstToken(TokenTypes.OBJBLOCK); |
| // count the number of direct children of the OBJBLOCK |
| // that are METHOD_DEFS |
| int methodDefs = objBlock.getChildCount(TokenTypes.METHOD_DEF); |
| // report error if limit is reached |
| if (methodDefs > max) { |
| log(ast.getLineNo(), |
| "too many methods, only " + max + " are allowed"); |
| } |
| } |
| } |
| +-----+ |
| |
| |
| * Building a JAR for your custom checks project |
| |
| To be able to use your custom checks in other projects, you need to package |
| and install them. To do that, just run this on the command line: |
| |
| +-----+ |
| mvn install |
| +-----+ |
| |
| This produces a JAR file with the following contents and installs it into your |
| local repository. |
| |
| ** <<<mycompany-checkstyle-checks-1.0.jar>>> |
| |
| +-----+ |
| mycompany-checkstyle-checks-1.0.jar |
| |-- pom.xml |
| |-- META-INF |
| | |-- MANIFEST.MF |
| | `-- maven |
| | `-- com.mycompany |
| | `-- mycompany-checkstyle-checks |
| | |-- pom.xml |
| | `-- pom.properties |
| `-- com |
| `-- mycompany |
| `-- checks |
| |-- packagenames.xml |
| `-- MethodLimitCheck.class |
| +-----+ |
| |
| |
| * Using your checks in another project |
| |
| Now you are ready to make use of your custom checks in another project. |
| |
| ** Create a Checkstyle configuration |
| |
| Create the file <<<checkstyle.xml>>> in the root of the project that wants to |
| use your custom checks. In this file you tell Checkstyle which checks you want |
| to use. |
| |
| <<Note:>> We don't have to specify the fully qualified classname of our check |
| here. That's because we used the <<<packagenames.xml>>> file earlier. |
| |
| +-----+ |
| <?xml version="1.0" ?> |
| |
| <!DOCTYPE module PUBLIC |
| "-//Puppy Crawl//DTD Check Configuration 1.2//EN" |
| "http://www.puppycrawl.com/dtds/configuration_1_2.dtd"> |
| |
| <module name="Checker"> |
| <module name="TreeWalker"> |
| <module name="MethodLimit"/> |
| </module> |
| </module> |
| +-----+ |
| |
| ** Configure the Checkstyle Plugin to use your custom checks |
| |
| Finally we need to tell the other project that you want it to use your custom |
| Checkstyle checks. In the <<<pom.xml>>> of that project, add the following |
| configuration. |
| |
| <<Note:>> You have to specify a plugin dependency on |
| <<<mycompany-checkstyle-checks>>> in the <<<\<build\>>>> element of your |
| <<<pom.xml>>>. It will not work inside the <<<\<reporting\>>>> element, |
| because <<<\<reporting\>>>> does not support plugin dependencies. The rest of |
| the configuration is done in the normal way in the <<<\<reporting\>>>> |
| element. |
| |
| +-----+ |
| <project> |
| ... |
| <build> |
| <plugins> |
| <plugin> |
| <groupId>org.apache.maven.plugins</groupId> |
| <artifactId>maven-checkstyle-plugin</artifactId> |
| <version>${project.version}</version> |
| <dependencies> |
| <dependency> |
| <groupId>com.mycompany</groupId> |
| <artifactId>mycompany-checkstyle-checks</artifactId> |
| <version>1.0</version> |
| </dependency> |
| </dependencies> |
| </plugin> |
| </plugins> |
| </build> |
| <reporting> |
| <plugins> |
| <plugin> |
| <groupId>org.apache.maven.plugins</groupId> |
| <artifactId>maven-checkstyle-plugin</artifactId> |
| <version>${project.version}</version> |
| <configuration> |
| <configLocation>checkstyle.xml</configLocation> |
| <packageNamesLocation>com/mycompany/checks/packagenames.xml</packageNamesLocation> |
| </configuration> |
| </plugin> |
| </plugins> |
| </reporting> |
| ... |
| </project> |
| +-----+ |