Add Checkstyle to the build process to increase and enforce continued code quality checks on the library. This can be done by adding Checkstyle to the Gradle setup, and defining a rules file.
Based on experience with Alloy, the Gradle modifications will look like (per project to apply to):
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
<!-- Doc for the modules used here may be found at http://checkstyle.sourceforge.net/checks.html -->
<module name = "Checker">
<property name="charset" value="UTF-8"/>
<property name="fileExtensions" value="java"/>
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module>
<module name="TreeWalker">
<!-- Checks that file name = outer class name -->
<module name="OuterTypeFilename"/>
<!-- Checks for unnecessary use of octal/unicode escape characters, which are less readable -->
<module name="IllegalTokenText">
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
<property name="format"
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
<property name="message"
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
</module>
<!-- Prevents using the unicode escape sequence, which is less reasable -->
<module name="AvoidEscapedUnicodeCharacters">
<property name="allowEscapesForControlCharacters" value="true"/>
<property name="allowByTailComment" value="true"/>
<property name="allowNonPrintableEscapes" value="true"/>
</module>
<!-- Checks for long lines - Long lines are hard to read in printouts or if developers have limited screen space for the source code -->
<module name="LineLength">
<property name="max" value="250"/>
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>
<!-- Ensures only one top-level class is defined per file, which aids in clarity when navigating a project's APIs -->
<module name="OneTopLevelClass"/>
<!-- Checks that import and package statements are not wrapped for readability -->
<module name="NoLineWrap"/>
<!-- EmptyBlock and EmptyCatchBlock - Checks for empty control statements, which avoids logic errors and silent removal of error tracking information -->
<module name="EmptyBlock">
<property name="option" value="TEXT"/>
<property name="tokens"
value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
</module>
<module name="EmptyCatchBlock">
<property name="exceptionVariableName" value="expected"/>
</module>
<!-- NeedsBraces, LeftCurly, and RightCurly check that braces are present for control statements, and are consistently placed within the code base -->
<module name="NeedBraces"/>
<module name="LeftCurly"/>
<module name="RightCurly">
<property name="id" value="RightCurlySame"/>
<property name="tokens"
value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE,
LITERAL_DO"/>
</module>
<module name="RightCurly">
<property name="id" value="RightCurlyAlone"/>
<property name="option" value="alone"/>
<property name="tokens"
value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT,
INSTANCE_INIT"/>
</module>
<!-- Checks that whitespace is consistently used around things like braces and other constructs -->
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true"/>
<property name="allowEmptyMethods" value="true"/>
<property name="allowEmptyTypes" value="true"/>
<property name="allowEmptyLoops" value="true"/>
<message key="ws.notFollowed"
value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
<message key="ws.notPreceded"
value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
</module>
<!-- Checks that only one statement (; terminated command) is present on each line for more consistent readability -->
<module name="OneStatementPerLine"/>
<!-- Checks that variables are each declared in a separate statement and line for more consistent readability -->
<module name="MultipleVariableDeclarations"/>
<!-- Enforces a consistent methodology of array declaration within the application -->
<module name="ArrayTypeStyle"/>
<!-- Checks for missing "default" clauses in switch statements, as this is a logic bugs -->
<module name="MissingSwitchDefault"/>
<!-- Checks for switch statements with associated code, but no ending control statement (continue, break, etc), as this is a logic bug -->
<module name="FallThrough"/>
<!-- Checks that Long constant values are defined with an upper-case 'L', as opposed to lower-case (lower can easily be confused for a one) -->
<module name="UpperEll"/>
<!-- Enforces consistent following of Java Language Specification modifier order guidelines -->
<module name="ModifierOrder"/>
<!-- SeparatorWrap enforces consistent styling of line wraps for given characters (newline before or after the character, etc) for readability -->
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapDot"/>
<property name="tokens" value="DOT"/>
<property name="option" value="nl"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapComma"/>
<property name="tokens" value="COMMA"/>
<property name="option" value="EOL"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapEllipsis"/>
<property name="tokens" value="ELLIPSIS"/>
<property name="option" value="EOL"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapArrayDeclarator"/>
<property name="tokens" value="ARRAY_DECLARATOR"/>
<property name="option" value="EOL"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapMethodRef"/>
<property name="tokens" value="METHOD_REF"/>
<property name="option" value="nl"/>
</module>
<!-- PackageName, TypeName, MemberName, ParameterName, CatchParameterName, LocalVariableName, MethodTypeParameterName and MethodName -->
<!-- Enforce standardized naming patterns for each of the mentioned Java elements -->
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
<message key="name.invalidPattern"
value="Package name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="TypeName">
<message key="name.invalidPattern"
value="Type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MemberName">
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
<message key="name.invalidPattern"
value="Member name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="CatchParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="LocalVariableName">
<property name="tokens" value="VARIABLE_DEF"/>
<property name="format" value="^[a-z]([a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MethodTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Method type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MethodName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
<message key="name.invalidPattern"
value="Method name ''{0}'' must match pattern ''{1}''."/>
</module>
<!-- Enforces that no 'finalize' method overrides exist, as these behave inconsistently and in-performantly -->
<module name="NoFinalizer"/>
<!-- MethodParamPad, NoWhitespaceBefore, ParenPad - Enforces consistent styling and whitespace use for readability -->
<module name="MethodParamPad"/>
<module name="NoWhitespaceBefore">
<property name="tokens"
value="COMMA, SEMI, POST_INC, POST_DEC, DOT, ELLIPSIS, METHOD_REF"/>
<property name="allowLineBreaks" value="true"/>
</module>
<module name="ParenPad"/>
<!-- Enforces consistent annotation placement for readability -->
<module name="AnnotationLocation">
<property name="id" value="AnnotationLocationMostCases"/>
<property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
</module>
<module name="AnnotationLocation">
<property name="id" value="AnnotationLocationVariables"/>
<property name="tokens" value="VARIABLE_DEF"/>
<property name="allowSamelineMultipleAnnotations" value="true"/>
</module>
</module>
</module>
Add Checkstyle to the build process to increase and enforce continued code quality checks on the library. This can be done by adding Checkstyle to the Gradle setup, and defining a rules file.
Based on experience with Alloy, the Gradle modifications will look like (per project to apply to):
And the starting rules file could be: