A. 什麼是checkstylehtml
wikipedia中給出的定義是這樣的:java
Checkstyle is a static code analysis tool used in software development for checking if Java source code complies with coding rules.android
從定義中能夠看到這樣幾點:express
1. staticapp
2. for JAVAcurl
3. coding ruleide
首先怎樣理解checkstyle是一種靜態代碼質量評估工具呢?statci means assessing the code quality without actually executing the code.(otherwise, it will be called dynamic code analysis),同時因爲靜態分析是基於source code,無須編譯或執行代碼,所以速度較快。工具
其次,咱們能夠經過配置module來配置對項目檢查哪些coding rule。coding rule的制定好比能夠參考sun的coding style或者google推出的coding style,好比google在今年二月份剛剛推出的最新版java coding style。測試
B. why checkstyle(在衆多的code quality工具中爲何選擇checkstyle呢?)gradle
1. Sonar
2. Simian
3. FindBugs
4. Cobertura
首先Sonar是一種開源的代碼質量評估工具,提供不少插件,好比使用gradle做爲構建工具,則經過運行gradle sA(short for sonar analysis),能夠生成code quality report,該report直觀提供項目中的tech debt的統計數據以及具體信息。但sonar的問題在於他能夠簡單的生成代碼質量報告,卻沒法保證開發人員會去看這個報告,並據此對代碼質量進行改進。與sonar不一樣,經過將checkstyle引入到項目構建中,能夠強制開發人員保證代碼質量,不然會拋出異常,構建失敗。
Simian(Similar Analyse)用於發現項目中的重複代碼;
FindBugs:使用靜態方法查找bug
Cobertura:用於計算java代碼的測試覆蓋率
C. 如何使用checkstyle
1. apply checkstyle plugin for gradle in build.gradle
apply plugin: checkstyle
對項目配置該checkstyle插件以後,相應的checkstyle的gradle task也就會自動加進去,包括:checkstyleMain, checkstyleTest, check。其中check task與前兩個task是dependent on的關係。
同時,配置該插件後,checkstyle會load文件config/checkstyle/checkstyle.xml做爲配置文件,該文件的內容即爲checkstyle rule。
2. run gradle check in command line
3. check the checkstyle report in the build output directory
D. checkstyle rule是怎樣制定的呢?
經過module對checkstyle rule進行配置。
一般會有SuppressionFilter,經過xml文件指定不對某些file進行某些checkstyle rule的檢查。
若是某個module沒有指定,說明不對那個module對應的rule進行檢查。
若是某個module被指定,但沒有property配置,則說明使用該module對應rule的默認值進行check。
若是某個module被指定,而且配置了property,則說明使用特定的參數對該module對應的rule進行check。
若是一個module被屢次指定,而且配置不一樣的property,則這些module之間是邏輯或的關係。
一般狀況下,對於產品代碼和測試代碼會採用不一樣的checkstyle rule的配置。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd"> <!-- This is a checkstyle configuration file. For descriptions of what the following rules do, please see the checkstyle configuration page at http://checkstyle.sourceforge.net/config.html --> <module name="Checker"> <module name="RegexpSingleline"> <property name="format" value="^(//| \*) Copyright (\([cC]\) )?[\d]{4}(\-[\d]{4})? (Google Inc\.).*$" /> <property name="minimum" value="1" /> <property name="maximum" value="10" /> <property name="message" value="Google copyright is missing or malformed." /> <property name="severity" value="error" /> </module> <module name="FileTabCharacter"> <!-- Checks that there are no tab characters in the file. --> </module> <module name="NewlineAtEndOfFile"/> <module name="RegexpSingleline"> <!-- Checks that FIXME is not used in comments. TODO is preferred. --> <property name="format" value="((//.*)|(\*.*))FIXME" /> <property name="message" value='TODO is preferred to FIXME. e.g. "TODO(johndoe): Refactor when v2 is released."' /> </module> <module name="RegexpSingleline"> <!-- Checks that TODOs are named. (Actually, just that they are followed by an open paren.) --> <property name="format" value="((//.*)|(\*.*))TODO[^(]" /> <property name="message" value='All TODOs should be named. e.g. "TODO(johndoe): Refactor when v2 is released."' /> </module> <!-- All Java AST specific tests live under TreeWalker module. --> <module name="TreeWalker"> <!-- IMPORT CHECKS --> <module name="RedundantImport"> <!-- Checks for redundant import statements. --> <property name="severity" value="error"/> </module> <module name="ImportOrder"> <!-- Checks for out of order import statements. --> <property name="severity" value="warning"/> <property name="groups" value="com.google,android,junit,net,org,java,javax"/> <!-- This ensures that static imports go first. --> <property name="option" value="top"/> <property name="tokens" value="STATIC_IMPORT, IMPORT"/> </module> <!-- JAVADOC CHECKS --> <!-- Checks for Javadoc comments. --> <!-- See http://checkstyle.sf.net/config_javadoc.html --> <module name="JavadocMethod"> <property name="scope" value="protected"/> <property name="severity" value="warning"/> <property name="allowMissingJavadoc" value="true"/> <property name="allowMissingParamTags" value="true"/> <property name="allowMissingReturnTag" value="true"/> <property name="allowMissingThrowsTags" value="true"/> <property name="allowThrowsTagsForSubclasses" value="true"/> <property name="allowUndeclaredRTE" value="true"/> </module> <module name="JavadocType"> <property name="scope" value="protected"/> <property name="severity" value="error"/> </module> <module name="JavadocStyle"> <property name="severity" value="warning"/> </module> <!-- NAMING CHECKS --> <!-- Item 38 - Adhere to generally accepted naming conventions --> <module name="PackageName"> <!-- Validates identifiers for package names against the supplied expression. --> <!-- Here the default checkstyle rule restricts package name parts to seven characters, this is not in line with common practice at Google. --> <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]{1,})*$"/> <property name="severity" value="warning"/> </module> <module name="TypeNameCheck"> <!-- Validates static, final fields against the expression "^[A-Z][a-zA-Z0-9]*$". --> <metadata name="altname" value="TypeName"/> <property name="severity" value="warning"/> </module> <module name="ConstantNameCheck"> <!-- Validates non-private, static, final fields against the supplied public/package final fields "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$". --> <metadata name="altname" value="ConstantName"/> <property name="applyToPublic" value="true"/> <property name="applyToProtected" value="true"/> <property name="applyToPackage" value="true"/> <property name="applyToPrivate" value="false"/> <property name="format" value="^([A-Z][A-Z0-9]*(_[A-Z0-9]+)*|FLAG_.*)$"/> <message key="name.invalidPattern" value="Variable ''{0}'' should be in ALL_CAPS (if it is a constant) or be private (otherwise)."/> <property name="severity" value="warning"/> </module> <module name="StaticVariableNameCheck"> <!-- Validates static, non-final fields against the supplied expression "^[a-z][a-zA-Z0-9]*_?$". --> <metadata name="altname" value="StaticVariableName"/> <property name="applyToPublic" value="true"/> <property name="applyToProtected" value="true"/> <property name="applyToPackage" value="true"/> <property name="applyToPrivate" value="true"/> <property name="format" value="^[a-z][a-zA-Z0-9]*_?$"/> <property name="severity" value="warning"/> </module> <module name="MemberNameCheck"> <!-- Validates non-static members against the supplied expression. --> <metadata name="altname" value="MemberName"/> <property name="applyToPublic" value="true"/> <property name="applyToProtected" value="true"/> <property name="applyToPackage" value="true"/> <property name="applyToPrivate" value="true"/> <property name="format" value="^[a-z][a-zA-Z0-9]*$"/> <property name="severity" value="warning"/> </module> <module name="MethodNameCheck"> <!-- Validates identifiers for method names. --> <metadata name="altname" value="MethodName"/> <property name="format" value="^[a-z][a-zA-Z0-9]*(_[a-zA-Z0-9]+)*$"/> <property name="severity" value="warning"/> </module> <module name="ParameterName"> <!-- Validates identifiers for method parameters against the expression "^[a-z][a-zA-Z0-9]*$". --> <property name="severity" value="warning"/> </module> <module name="LocalFinalVariableName"> <!-- Validates identifiers for local final variables against the expression "^[a-z][a-zA-Z0-9]*$". --> <property name="severity" value="warning"/> </module> <module name="LocalVariableName"> <!-- Validates identifiers for local variables against the expression "^[a-z][a-zA-Z0-9]*$". --> <property name="severity" value="warning"/> </module> <!-- LENGTH and CODING CHECKS --> <module name="LineLength"> <!-- Checks if a line is too long. --> <property name="max" value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.max}" default="100"/> <property name="severity" value="error"/> <!-- The default ignore pattern exempts the following elements: - import statements - long URLs inside comments --> <property name="ignorePattern" value="${com.puppycrawl.tools.checkstyle.checks.sizes.LineLength.ignorePattern}" default="^(package .*;\s*)|(import .*;\s*)|( *\* *https?://.*)$"/> </module> <module name="LeftCurly"> <!-- Checks for placement of the left curly brace ('{'). --> <property name="severity" value="warning"/> </module> <module name="RightCurly"> <!-- Checks right curlies on CATCH, ELSE, and TRY blocks are on the same line. e.g., the following example is fine: <pre> if { ... } else </pre> --> <!-- This next example is not fine: <pre> if { ... } else </pre> --> <property name="option" value="same"/> <property name="severity" value="warning"/> </module> <!-- Checks for braces around if and else blocks --> <module name="NeedBraces"> <property name="severity" value="warning"/> <property name="tokens" value="LITERAL_IF, LITERAL_ELSE, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO"/> </module> <module name="UpperEll"> <!-- Checks that long constants are defined with an upper ell.--> <property name="severity" value="error"/> </module> <module name="FallThrough"> <!-- Warn about falling through to the next case statement. Similar to javac -Xlint:fallthrough, but the check is suppressed if a single-line comment on the last non-blank line preceding the fallen-into case contains 'fall through' (or some other variants which we don't publicized to promote consistency). --> <property name="reliefPattern" value="fall through|Fall through|fallthru|Fallthru|falls through|Falls through|fallthrough|Fallthrough|No break|NO break|no break|continue on"/> <property name="severity" value="error"/> </module> <!-- MODIFIERS CHECKS --> <module name="ModifierOrder"> <!-- Warn if modifier order is inconsistent with JLS3 8.1.1, 8.3.1, and 8.4.3. The prescribed order is: public, protected, private, abstract, static, final, transient, volatile, synchronized, native, strictfp --> </module> <!-- WHITESPACE CHECKS --> <module name="WhitespaceAround"> <!-- Checks that various tokens are surrounded by whitespace. This includes most binary operators and keywords followed by regular or curly braces. --> <property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, EQUAL, GE, GT, LAND, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, SL, SL_ASSIGN, SR_ASSIGN, STAR, STAR_ASSIGN"/> <property name="severity" value="error"/> </module> <module name="WhitespaceAfter"> <!-- Checks that commas, semicolons and typecasts are followed by whitespace. --> <property name="tokens" value="COMMA, SEMI, TYPECAST"/> </module> <module name="NoWhitespaceAfter"> <!-- Checks that there is no whitespace after various unary operators. Linebreaks are allowed. --> <property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS, UNARY_PLUS"/> <property name="allowLineBreaks" value="true"/> <property name="severity" value="error"/> </module> <module name="NoWhitespaceBefore"> <!-- Checks that there is no whitespace before various unary operators. Linebreaks are allowed. --> <property name="tokens" value="SEMI, DOT, POST_DEC, POST_INC"/> <property name="allowLineBreaks" value="true"/> <property name="severity" value="error"/> </module> <module name="ParenPad"> <!-- Checks that there is no whitespace before close parens or after open parens. --> <property name="severity" value="warning"/> </module> </module> </module>