Вы можете попробовать
https://checkstyle.sourceforge.io/config_filters.html#SuppressionXpathFilter
Вы можете настроить его как:
<module name="SuppressionXpathFilter">
<property name="file" value="suppressions-xpath.xml"/>
<property name="optional" value="false"/>
</module>
Сгенерируйте подавления Xpath, используя CLI с опцией -g, и укажите выходные данные, используя ключ -o.
https://checkstyle.sourceforge.io/cmdline.html#Command_line_usage
Вот фрагмент кода муравья, который поможет вам настроить автогенерацию подавления Checkstyle:
<target name="checkstyleg">
<move file="suppressions-xpath.xml"
tofile="suppressions-xpath.xml.bak"
preservelastmodified="true"
force="true"
failonerror="false"
verbose="true"/>
<fileset dir="${basedir}"
id="javasrcs">
<include name="**/*.java" />
</fileset>
<pathconvert property="sources"
refid="javasrcs"
pathsep=" " />
<loadfile property="cs.cp"
srcFile="../${cs.classpath.file}" />
<java classname="${cs.main.class}"
logError="true">
<arg line="-c ../${cs.config} -p ${cs.properties} -o ${ant.project.name}-xpath.xml -g ${sources}" />
<classpath>
<pathelement path="${cs.cp}" />
<pathelement path="${java.class.path}" />
</classpath>
</java>
<condition property="file.is.empty" else="false">
<length file="${ant.project.name}-xpath.xml" when="equal" length="0" />
</condition>
<if>
<equals arg1="${file.is.empty}" arg2="false"/>
<then>
<move file="${ant.project.name}-xpath.xml"
tofile="suppressions-xpath.xml"
preservelastmodified="true"
force="true"
failonerror="true"
verbose="true"/>
</then>
</if>
</target>
Suppressions-xpath.xml указывается в качестве источника подавлений Xpath в конфигурации правил Checkstyle. В приведенном выше фрагменте я загружаю путь класса Checkstyle из файла cs.cp в свойство. Вы можете указать путь к классу напрямую.
Или вы можете использовать groovy в Maven (или Ant), чтобы сделать то же самое:
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import java.nio.file.Paths
def backupSuppressions() {
def supprFileName =
project.properties["checkstyle.suppressionsFile"]
def suppr = Paths.get(supprFileName)
def target = null
if (Files.exists(suppr)) {
def supprBak = Paths.get(supprFileName + ".bak")
target = Files.move(suppr, supprBak,
StandardCopyOption.REPLACE_EXISTING)
println "Backed up " + supprFileName
}
return target
}
def renameSuppressions() {
def supprFileName =
project.properties["checkstyle.suppressionsFile"]
def suppr = Paths.get(project.name + "-xpath.xml")
def target = null
if (Files.exists(suppr)) {
def supprNew = Paths.get(supprFileName)
target = Files.move(suppr, supprNew)
println "Renamed " + suppr + " to " + supprFileName
}
return target
}
def getClassPath(classLoader, sb) {
classLoader.getURLs().each {url->
sb.append("${url.getFile().toString()}:")
}
if (classLoader.parent) {
getClassPath(classLoader.parent, sb)
}
return sb.toString()
}
backupSuppressions()
def cp = getClassPath(this.class.classLoader,
new StringBuilder())
def csMainClass =
project.properties["cs.main.class"]
def csRules =
project.properties["checkstyle.rules"]
def csProps =
project.properties["checkstyle.properties"]
String[] args = ["java", "-cp", cp,
csMainClass,
"-c", csRules,
"-p", csProps,
"-o", project.name + "-xpath.xml",
"-g", "src"]
ProcessBuilder pb = new ProcessBuilder(args)
pb = pb.inheritIO()
Process proc = pb.start()
proc.waitFor()
renameSuppressions()
Единственный недостаток использования подавлений Xpath - помимо проверок, которые он не поддерживает - это если у вас есть код, подобный следующему:
package cstests;
public interface TestMagicNumber {
static byte[] getAsciiRotator() {
byte[] rotation = new byte[95 * 2];
for (byte i = ' '; i <= '~'; i++) {
rotation[i - ' '] = i;
rotation[i + 95 - ' '] = i;
}
return rotation;
}
}
Подавление Xpath, сгенерированное в этом случае, не принимается Checkstyle, и проверка завершается с ошибкой с исключением:
<suppress-xpath
files="TestMagicNumber.java"
checks="MagicNumberCheck"
query="/INTERFACE_DEF[./IDENT[@text='TestMagicNumber']]/OBJBLOCK/METHOD_DEF[./IDENT[@text='getAsciiRotator']]/SLIST/LITERAL_FOR/SLIST/EXPR/ASSIGN[./IDENT[@text='i']]/INDEX_OP[./IDENT[@text='rotation']]/EXPR/MINUS[./CHAR_LITERAL[@text='' '']]/PLUS[./IDENT[@text='i']]/NUM_INT[@text='95']"/>
Генерация подавлений Xpath рекомендуется, когда вы исправили все другие нарушения и хотите подавить все остальные. Это не позволит вам выбрать конкретные экземпляры в коде для подавления. Вы можете, однако, выбрать и выбрать подавления из сгенерированного файла, чтобы сделать именно это.
SuppressionXpathSingleFilter лучше подходит для идентификации и подавления определенного правила, файла или сообщения об ошибке. Вы можете настроить несколько фильтров, идентифицирующих каждый по атрибуту id.
https://checkstyle.sourceforge.io/config_filters.html#SuppressionXpathSingleFilter