南沙網(wǎng)站建設(shè)小說搜索風(fēng)云榜
最近的Java后端項(xiàng)目想實(shí)現(xiàn)代碼的規(guī)范檢查,調(diào)研了一圈,終于找到了簡(jiǎn)單的方式實(shí)現(xiàn):以下是常見的幾種方案:
1、在客戶端做 git hook,主要是用?pre-commit?這個(gè)鉤子。前端項(xiàng)目中常見的 husky 就是基于此實(shí)現(xiàn)的。但缺點(diǎn)也很明顯,就是在本地把這個(gè)鉤子刪了、或者?git commit --no-verify?就繞開了。不過小團(tuán)隊(duì)、大家約定好的話這種方案是最方便的。
2、在服務(wù)端做 git hook,主要是用?pre-receive?這個(gè)鉤子。
3、不限制 push、但通過其他方式限制。比如可以通過 CI 限制,例如在 forking-workflow 模式中設(shè)置在 Merge 時(shí)自動(dòng)執(zhí)行一個(gè) Actions 來執(zhí)行 Lint,對(duì)于不合格的 Merge Request 直接關(guān)閉掉不允許合并,以變相到達(dá)不合格代碼進(jìn)入主干的目的。
其中 1、2 兩點(diǎn)跟 GitLab 無關(guān),需要的都是寫 Shell 腳本而已。第 3 種可以在 GitLab 用圖形化方式設(shè)置。
小團(tuán)隊(duì)的第一種用的比較多;大團(tuán)隊(duì)這一步驟大多是跟 CI/CD 工作流緊密結(jié)合的。
我們用的方式是第一種在客戶端校驗(yàn),加上checkStyle 工具包,checkStyle可以直接在IDEA插件中搜索。
?
下載Checkstyle jar包 官網(wǎng)地址,GitHulb,目前最近版本為checkstyle-8.12-all.jar
下載對(duì)應(yīng)的規(guī)范約束xml文件,目前主要是有三種Alibaba_check.xml、sun_checks.xml 和google_checks.xml
我們用的完整的規(guī)范如下:
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC"-//Puppy Crawl//DTD Check Configuration 1.3//EN""http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!--文件描述:阿里巴巴代碼規(guī)范完整版-->
<!--創(chuàng)建日期:20230203-->
<!--創(chuàng)建人:QC班長(zhǎng)-->
<module name="Checker"><!-- 檢查文件是否以一個(gè)空行結(jié)束 --><module name="NewlineAtEndOfFile"/><!-- 長(zhǎng)度檢查 --><!-- 每行不超過120個(gè)字符 --><module name="LineLength"><property name="max" value="120" /></module><!-- 文件長(zhǎng)度不超過1500行 --><module name="FileLength"><property name="max" value="1500"/></module><!-- 每個(gè)java文件一個(gè)語法樹 --><module name="TreeWalker"><!-- import檢查--><!-- 避免使用* -->
<!-- <module name="AvoidStarImport">-->
<!-- <property name="excludes" value="java.io,java.net,java.lang.Math"/>-->
<!-- <!– 實(shí)例;import java.util.*;.–>-->
<!-- <property name="allowClassImports" value="false"/>-->
<!-- <!– 實(shí)例 ;import static org.junit.Assert.*;–>-->
<!-- <property name="allowStaticMemberImports" value="true"/>-->
<!-- </module>--><!-- 檢查是否從非法的包中導(dǎo)入了類 --><module name="IllegalImport"/><!-- 檢查是否導(dǎo)入了多余的包 --><module name="RedundantImport"/><!-- 沒用的import檢查,比如:1.沒有被用到2.重復(fù)的3.import java.lang的4.import 與該類在同一個(gè)package的 --><module name="UnusedImports" /><!-- 注釋檢查 --><!-- 檢查方法和構(gòu)造函數(shù)的javadoc --><module name="JavadocType"><property name="allowUnknownTags" value="true"/><message key="javadoc.missing" value="類注釋:缺少Javadoc注釋。"/></module><!-- 命名檢查 --><!-- 局部的final變量,包括catch中的參數(shù)的檢查 --><module name="LocalFinalVariableName" /><!-- 局部的非final型的變量,包括catch中的參數(shù)的檢查 --><module name="LocalVariableName" /><!-- 包名的檢查(只允許小寫字母),默認(rèn)^[a-z]+(\.[a-zA-Z_][a-zA-Z_0-9_]*)*$ --><module name="PackageName"><property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$" /><message key="name.invalidPattern" value="包名 ''{0}'' 要符合 ''{1}''格式."/></module><!-- 僅僅是static型的變量(不包括static final型)的檢查 --><module name="StaticVariableName" /><!-- Class或Interface名檢查,默認(rèn)^[A-Z][a-zA-Z0-9]*$--><module name="TypeName"><property name="severity" value="warning"/><message key="name.invalidPattern" value="名稱 ''{0}'' 要符合 ''{1}''格式."/></module><!-- 非static型變量的檢查 --><module name="MemberName" /><!-- 方法名的檢查 --><module name="MethodName" /><!-- 方法的參數(shù)名 --><module name="ParameterName " /><!-- 常量名的檢查(只允許大寫),默認(rèn)^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$ --><module name="ConstantName" /><!-- 定義檢查 --><!-- 檢查數(shù)組類型定義的樣式 --><module name="ArrayTypeStyle"/><!-- 檢查long型定義是否有大寫的“L” --><module name="UpperEll"/><!-- 方法不超過50行 --><module name="MethodLength"><property name="tokens" value="METHOD_DEF" /><property name="max" value="50" /></module><!-- 方法的參數(shù)個(gè)數(shù)不超過5個(gè)。 并且不對(duì)構(gòu)造方法進(jìn)行檢查--><module name="ParameterNumber"><property name="max" value="5" /><property name="ignoreOverriddenMethods" value="true"/><property name="tokens" value="METHOD_DEF" /></module><!-- 空格檢查--><!-- 方法名后跟左圓括號(hào)"(" --><module name="MethodParamPad" /><!-- 在類型轉(zhuǎn)換時(shí),不允許左圓括號(hào)右邊有空格,也不允許與右圓括號(hào)左邊有空格 --><module name="TypecastParenPad" /><!-- 檢查在某個(gè)特定關(guān)鍵字之后應(yīng)保留空格 --><module name="NoWhitespaceAfter"/><!-- 檢查在某個(gè)特定關(guān)鍵字之前應(yīng)保留空格 --><module name="NoWhitespaceBefore"/><!-- 操作符換行策略檢查 --><module name="OperatorWrap"/><!-- 圓括號(hào)空白 --><module name="ParenPad"/><!-- 檢查分隔符是否在空白之后 --><module name="WhitespaceAfter"/><!-- 檢查分隔符周圍是否有空白 --><module name="WhitespaceAround"/><!-- 修飾符檢查 --><!-- 檢查修飾符的順序是否遵照java語言規(guī)范,默認(rèn)public、protected、private、abstract、static、final、transient、volatile、synchronized、native、strictfp --><module name="ModifierOrder"/><!-- 檢查接口和annotation中是否有多余修飾符,如接口方法不必使用public --><module name="RedundantModifier"/><!-- 代碼塊檢查 --><!-- 檢查是否有嵌套代碼塊 --><module name="AvoidNestedBlocks"/><!-- 檢查是否有空代碼塊 --><module name="EmptyBlock"/><!-- 檢查左大括號(hào)位置 --><module name="LeftCurly"/><!-- 檢查代碼塊是否缺失{} --><module name="NeedBraces"/><!-- 檢查右大括號(hào)位置 --><module name="RightCurly"/><!-- 代碼檢查 --><!-- 檢查空的代碼段 --><module name="EmptyStatement"/><!-- 檢查在重寫了equals方法后是否重寫了hashCode方法 --><module name="EqualsHashCode"/><!-- 檢查局部變量或參數(shù)是否隱藏了類中的變量 --><module name="HiddenField"><property name="tokens" value="VARIABLE_DEF"/></module><!-- 檢查是否使用工廠方法實(shí)例化 --><module name="IllegalInstantiation"/><!-- 檢查子表達(dá)式中是否有賦值操作 --><module name="InnerAssignment"/><!-- 檢查是否有"魔術(shù)"數(shù)字 --><module name="MagicNumber"><property name="ignoreNumbers" value="0, 1"/><property name="ignoreAnnotation" value="true"/></module><!-- 檢查switch語句是否有default --><module name="MissingSwitchDefault"/><!-- 檢查是否有過度復(fù)雜的布爾表達(dá)式 --><module name="SimplifyBooleanExpression"/><!-- 檢查是否有過于復(fù)雜的布爾返回代碼段 --><module name="SimplifyBooleanReturn"/><!-- 類設(shè)計(jì)檢查 --><!-- 檢查類是否為擴(kuò)展設(shè)計(jì)l --><!-- 檢查只有private構(gòu)造函數(shù)的類是否聲明為final --><module name="FinalClass"/><!-- 檢查工具類是否有putblic的構(gòu)造器 --><module name="HideUtilityClassConstructor"/><!-- 檢查接口是否僅定義類型 --><module name="InterfaceIsType"/><!-- 檢查類成員的可見度 檢查類成員的可見性。只有static final 成員是public的除非在本檢查的protectedAllowed和packagedAllowed屬性中進(jìn)行了設(shè)置--><module name="VisibilityModifier"><property name="packageAllowed" value="true"/><property name="protectedAllowed" value="true"/></module><!-- 語法 --><!-- String的比較不能用!= 和 == --><module name="StringLiteralEquality"/><!-- 限制for循環(huán)最多嵌套2層 --><module name="NestedForDepth"><property name="max" value="2"/></module><!-- if最多嵌套3層 --><module name="NestedIfDepth"><property name="max" value="3"/></module><!-- 檢查未被注釋的main方法,排除以Appllication結(jié)尾命名的類 --><module name="UncommentedMain"><property name="excludedClasses" value=".*Application$"/></module><!-- 禁止使用System.out.println --><module name="Regexp"><property name="format" value="System\.out\.println"/><property name="illegalPattern" value="true"/></module><!-- return個(gè)數(shù) 3個(gè)--><module name="ReturnCount"><property name="max" value="3"/></module><!--try catch 異常處理數(shù)量 3--><module name="NestedTryDepth "><property name="max" value="3"/></module><!-- clone方法必須調(diào)用了super.clone() --><module name="SuperClone" /><!-- finalize 必須調(diào)用了super.finalize() --><module name="SuperFinalize" /></module>
</module>
IDEA中的配置
代碼規(guī)范檢測(cè)工具配置
打開file --> settings,找到Plugins ,輸入 checkStyle-IDEA,點(diǎn)擊install 安裝
考慮到CheckStyle提供的校驗(yàn)規(guī)則很嚴(yán)格,這里我們用自定義的校驗(yàn)規(guī)則[alibaba-checks.xml]
打開file --> settings,找到Tools ,可以看到安裝好的 checkstyle,Configuration File-->點(diǎn)擊?添加項(xiàng)目中的配置文件,選擇checks/alibaba-checks.xml文件,輸入名稱,點(diǎn)擊下一步,完成。
?這樣子就好了,不符合規(guī)范的代碼會(huì)直接標(biāo)紅顯示
?參考文獻(xiàn):
1、java代碼提交到git服務(wù)器如何能自動(dòng)檢查代碼規(guī)范? - SegmentFault 思否
2、git下使用checkstyle構(gòu)建代碼風(fēng)格檢查_唯一昵稱真難的博客-CSDN博客_checkstyle+git?
3、符合阿里巴巴代碼規(guī)范的checkstyle檢測(cè)文件_KimZing的博客-CSDN博客?
4、pre-commit?
5、使用 pre-commit 實(shí)現(xiàn)代碼檢查_清歡守護(hù)者的博客-CSDN博客?