Wednesday, April 21, 2010

Using Checkstyle with Android Open Source Project

This post provides a small Checkstyle template that we have been using to conform with the code style guide proposed by the Android Open Source Project. For pure formatting issues also see this question on stackoverflow.

1. Make sure that the Checkstyle plugin is installed in Eclipse. If not, follow the steps below. Note that these instructions are for Eclipse Galileo. If you are using another version, some of the installation steps might differ.
            1. Open "Help" -> "Install New Software"
            2. Paste the link: http://eclipse-cs.sf.net/update into the "Work with:" field and click "Add..."
            3. Name the site e.g. "Checkstyle"
            4. Check the box next to the latest version of the Checkstyle plugin and press "Next->"
            5. Follow the instructions to complete the installation

2. Save the contents below to a new xml file and place it on a location of your choice.
3. Open "Window" -> "Preferences" and choose Checkstyle
4. Press "New..."
5. Fill in the configuration properties
            "Type: External Configuration File"
            "Name: Android checkstyle by Enea"
            "Location:" Browse to the saved android_cs.xml file
6. Press OK twice

7. Right click on your Android project and choose Properties
8. Choose Checkstyle and check the box "Checkstyle active for this project"
9. Select "Android checkstyle by Enea" from the drop down list
10. Rebuild the project to analyze your code

Done!

Karin, Fredrik and Karl

Note: If you want to edit the checkstyle configuration open "Window" -> "Preferences" and choose Checkstyle.
Mark the Check Configuration you want to edit and press "Properties..."

Save this to an .xml file.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "https://home.enea.com/dtds/,DanaInfo=www.puppycrawl.com,CT=dtd+configuration_1_3.dtd">

<!--
    This configuration file was written by the eclipse-cs plugin configuration editor
-->
<!--
    Checkstyle-Configuration: Android checkstyle by Enea
    Description: none
-->
<module name="Checker">
  <property name="severity" value="warning"></property>
  <module name="TreeWalker">
    <property name="tabWidth" value="4"></property>
    <module name="JavadocMethod">
      <property name="logLoadErrors" value="true"></property>
      <property name="suppressLoadErrors" value="true"></property>
    </module>
    <module name="JavadocType"></module>
    <module name="JavadocVariable"></module>
    <module name="JavadocStyle"></module>
    <module name="ConstantName"></module>
    <module name="LocalFinalVariableName"></module>
    <module name="LocalVariableName"></module>
    <module name="MemberName">
      <metadata name="net.sf.eclipsecs.core.comment" value="only public starts without m"></metadata>
      <property name="applyToProtected" value="false"></property>
      <property name="applyToPrivate" value="false"></property>
    </module>
    <module name="MethodName"></module>
    <module name="PackageName"></module>
    <module name="ParameterName"></module>
    <module name="StaticVariableName">
      <metadata name="net.sf.eclipsecs.core.comment" value="starts with 's'"></metadata>
      <property name="format" value="^[s][a-zA-Z0-9]*$"></property>
    </module>
    <module name="TypeName"></module>
    <module name="AvoidStarImport"></module>
    <module name="IllegalImport"></module>
    <module name="RedundantImport"></module>
    <module name="UnusedImports"></module>
    <module name="LineLength">
      <property name="severity" value="ignore"></property>
      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"></metadata>
    </module>
    <module name="MethodLength"></module>
    <module name="ParameterNumber"></module>
    <module name="EmptyForIteratorPad"></module>
    <module name="MethodParamPad"></module>
    <module name="NoWhitespaceAfter">
      <property name="tokens" value="BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"></property>
    </module>
    <module name="NoWhitespaceBefore"></module>
    <module name="OperatorWrap"></module>
    <module name="ParenPad"></module>
    <module name="TypecastParenPad"></module>
    <module name="WhitespaceAfter"></module>
    <module name="WhitespaceAround"></module>
    <module name="ModifierOrder"></module>
    <module name="RedundantModifier"></module>
    <module name="AvoidNestedBlocks"></module>
    <module name="EmptyBlock"></module>
    <module name="LeftCurly"></module>
    <module name="NeedBraces"></module>
    <module name="RightCurly"></module>
    <module name="AvoidInlineConditionals"></module>
    <module name="DoubleCheckedLocking"></module>
    <module name="EmptyStatement"></module>
    <module name="EqualsHashCode"></module>
    <module name="HiddenField"></module>
    <module name="IllegalInstantiation"></module>
    <module name="InnerAssignment"></module>
    <module name="MagicNumber"></module>
    <module name="MissingSwitchDefault"></module>
    <module name="RedundantThrows">
      <property name="logLoadErrors" value="true"></property>
      <property name="suppressLoadErrors" value="true"></property>
    </module>
    <module name="SimplifyBooleanExpression"></module>
    <module name="SimplifyBooleanReturn"></module>
    <module name="DesignForExtension">
      <property name="severity" value="ignore"></property>
      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"></metadata>
    </module>
    <module name="FinalClass"></module>
    <module name="HideUtilityClassConstructor"></module>
    <module name="InterfaceIsType"></module>
    <module name="VisibilityModifier"></module>
    <module name="ArrayTypeStyle"></module>
    <module name="FinalParameters">
      <property name="severity" value="ignore"></property>
      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"></metadata>
    </module>
    <module name="TodoComment">
      <property name="severity" value="ignore"></property>
      <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"></metadata>
    </module>
    <module name="UpperEll"></module>
    <module name="MethodLength">
      <property name="max" value="40"></property>
    </module>
    <module name="MemberName">
      <metadata name="net.sf.eclipsecs.core.comment" value="non public members should start with m"></metadata>
      <property name="applyToPublic" value="false"></property>
      <property name="format" value="^[m][a-zA-Z0-9]*$"></property>
    </module>
    <module name="LineLength">
      <property name="max" value="100"></property>
    </module>
  </module>
  <module name="JavadocPackage"></module>
  <module name="NewlineAtEndOfFile">
    <property name="severity" value="ignore"></property>
    <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"></metadata>
  </module>
  <module name="Translation"></module>
  <module name="FileTabCharacter">
    <property name="severity" value="ignore"></property>
    <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"></metadata>
  </module>
  <module name="RegexpSingleline">
    <property name="severity" value="ignore"></property>
    <property name="format" value="\s+$"></property>
    <property name="message" value="Line has trailing spaces."></property>
    <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"></metadata>
  </module>
</module>