Initial commit
This commit is contained in:
commit
92cca73cfc
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
$problemsCount = 0;
|
||||
$html = '';
|
||||
$reportsPath = $argv[1];
|
||||
$fileNames = scandir($reportsPath);
|
||||
$fileNames = array_slice($fileNames, 3);
|
||||
foreach ($fileNames as $fileName) {
|
||||
$filepath = $reportsPath.DIRECTORY_SEPARATOR.$fileName;
|
||||
$xml = simplexml_load_file($filepath);
|
||||
foreach ($xml->problem as $problem) {
|
||||
if ($problem->description == 'File is too complex to perform context-sensitive data-flow analysis') {
|
||||
continue;
|
||||
}
|
||||
$problemsCount++;
|
||||
$html .= '<tr><td>'.$problemsCount.'</td><td>'.$problem->file.'</td><td>'.$problem->line.'</td><td>'.$problem->description.'</td></tr>';
|
||||
}
|
||||
}
|
||||
if ($problemsCount > 0) {
|
||||
$html = '<table border cellpadding="5"><tr>'
|
||||
.'<td align="center" bgcolor="LightGray"><b>Num</b></td>'
|
||||
.'<td align="center" bgcolor="LightGray"><b>File</b></td>'
|
||||
.'<td align="center" bgcolor="LightGray"><b>Line</b></td>'
|
||||
.'<td align="center" bgcolor="LightGray"><b>Problem</b></td><tr>'.$html.'</table>';
|
||||
echo 'Found inspection problems: '.$problemsCount.PHP_EOL;
|
||||
} else {
|
||||
$html = '<h1 align="center">No inspection problems found</h1>';
|
||||
}
|
||||
$html = '<html><head></head><body>'.$html.'</body></html>';
|
||||
file_put_contents($reportsPath.DIRECTORY_SEPARATOR.'appcode_inspections.html', $html);
|
||||
?>
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
||||
|
||||
<!--
|
||||
|
||||
Checkstyle configuration that checks the Google coding conventions from:
|
||||
|
||||
- Google Java Style
|
||||
https://google-styleguide.googlecode.com/svn-history/r130/trunk/javaguide.html
|
||||
|
||||
Checkstyle is very configurable. Be sure to read the documentation at
|
||||
http://checkstyle.sf.net (or in your downloaded distribution).
|
||||
|
||||
Most Checks are configurable, be sure to consult the documentation.
|
||||
|
||||
To completely disable a check, just comment it out or delete it from the file.
|
||||
|
||||
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
|
||||
|
||||
-->
|
||||
|
||||
<module name = "Checker">
|
||||
<property name="charset" value="UTF-8"/>
|
||||
|
||||
<property name="severity" value="warning"/>
|
||||
|
||||
<property name="fileExtensions" value="java, properties, xml"/>
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
|
||||
<module name="FileTabCharacter">
|
||||
<property name="eachLine" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<module name="OuterTypeFilename"/>
|
||||
<module name="IllegalTokenText">
|
||||
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
|
||||
<property name="format" value="\\u00(08|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="Avoid using corresponding octal or Unicode escape."/>
|
||||
</module>
|
||||
<module name="AvoidEscapedUnicodeCharacters">
|
||||
<property name="allowEscapesForControlCharacters" value="true"/>
|
||||
<property name="allowByTailComment" value="true"/>
|
||||
<property name="allowNonPrintableEscapes" value="true"/>
|
||||
</module>
|
||||
<module name="LineLength">
|
||||
<property name="max" value="150"/>
|
||||
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
|
||||
</module>
|
||||
<module name="MethodLength">
|
||||
<property name="max" value="40"/>
|
||||
</module>
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="OneTopLevelClass"/>
|
||||
<module name="NoLineWrap"/>
|
||||
<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="NeedBraces"/>
|
||||
<module name="LeftCurly">
|
||||
<property name="maxLineLength" value="150"/>
|
||||
</module>
|
||||
<module name="RightCurly"/>
|
||||
<module name="RightCurly">
|
||||
<property name="option" value="alone"/>
|
||||
<property name="tokens" value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, LITERAL_DO, STATIC_INIT, INSTANCE_INIT"/>
|
||||
</module>
|
||||
<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>
|
||||
<module name="OneStatementPerLine"/>
|
||||
<module name="MultipleVariableDeclarations"/>
|
||||
<module name="ArrayTypeStyle"/>
|
||||
<module name="MissingSwitchDefault"/>
|
||||
<module name="FallThrough"/>
|
||||
<module name="UpperEll"/>
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="EmptyLineSeparator">
|
||||
<property name="allowNoEmptyLineBetweenFields" value="true"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="tokens" value="DOT"/>
|
||||
<property name="option" value="nl"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="tokens" value="COMMA"/>
|
||||
<property name="option" value="EOL"/>
|
||||
</module>
|
||||
<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-z0-9][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="LocalVariableName">
|
||||
<property name="tokens" value="VARIABLE_DEF"/>
|
||||
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
|
||||
<property name="allowOneCharVarInForLoop" value="true"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="ClassTypeParameterName">
|
||||
<property name="format" value="^[T]([A-Z][a-zA-Z0-9]*)?$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Class type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="MethodTypeParameterName">
|
||||
<property name="format" value="^[T]([A-Z][a-zA-Z0-9]*)?$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Method type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="NoFinalizer"/>
|
||||
<module name="GenericWhitespace">
|
||||
<message key="ws.followed"
|
||||
value="GenericWhitespace ''{0}'' is followed by whitespace."/>
|
||||
<message key="ws.preceded"
|
||||
value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
|
||||
<message key="ws.illegalFollow"
|
||||
value="GenericWhitespace ''{0}'' should followed by whitespace."/>
|
||||
<message key="ws.notPreceded"
|
||||
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
|
||||
</module>
|
||||
<module name="Indentation">
|
||||
<property name="basicOffset" value="4"/>
|
||||
<property name="braceAdjustment" value="0"/>
|
||||
<property name="caseIndent" value="4"/>
|
||||
<property name="throwsIndent" value="4"/>
|
||||
<property name="lineWrappingIndentation" value="4"/>
|
||||
<property name="arrayInitIndent" value="4"/>
|
||||
</module>
|
||||
<module name="AbbreviationAsWordInName">
|
||||
<property name="ignoreFinal" value="false"/>
|
||||
<property name="allowedAbbreviationLength" value="1"/>
|
||||
</module>
|
||||
<module name="OverloadMethodsDeclarationOrder"/>
|
||||
<module name="VariableDeclarationUsageDistance"/>
|
||||
<module name="MethodParamPad"/>
|
||||
<module name="OperatorWrap">
|
||||
<property name="option" value="NL"/>
|
||||
<property name="tokens" value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR "/>
|
||||
</module>
|
||||
<module name="AnnotationLocation">
|
||||
<property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
|
||||
</module>
|
||||
<module name="AnnotationLocation">
|
||||
<property name="tokens" value="VARIABLE_DEF"/>
|
||||
<property name="allowSamelineMultipleAnnotations" value="true"/>
|
||||
</module>
|
||||
<module name="NonEmptyAtclauseDescription"/>
|
||||
<module name="JavadocTagContinuationIndentation"/>
|
||||
<module name="SummaryJavadocCheck">
|
||||
<property name="forbiddenSummaryFragments" value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
|
||||
</module>
|
||||
<module name="JavadocParagraph"/>
|
||||
<module name="AtclauseOrder">
|
||||
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
|
||||
<property name="target" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
|
||||
</module>
|
||||
<module name="JavadocMethod">
|
||||
<property name="scope" value="nothing"/>
|
||||
<property name="allowMissingParamTags" value="true"/>
|
||||
<property name="allowMissingThrowsTags" value="true"/>
|
||||
<property name="allowMissingReturnTag" value="true"/>
|
||||
<property name="minLineCount" value="2"/>
|
||||
<property name="allowedAnnotations" value="Override, Test"/>
|
||||
<property name="allowThrowsTagsForSubclasses" value="true"/>
|
||||
</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>
|
||||
<module name="SingleLineJavadoc"/>
|
||||
<module name="EmptyCatchBlock">
|
||||
<property name="exceptionVariableName" value="expected"/>
|
||||
</module>
|
||||
<module name="SuppressWarningsHolder" />
|
||||
</module>
|
||||
<module name="SuppressWarningsFilter" />
|
||||
</module>
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<FindBugsFilter>
|
||||
<Match>
|
||||
<!-- ignore all issues in resource generation -->
|
||||
<Class name="~.*\.R\$.*"/>
|
||||
</Match>
|
||||
<Match>
|
||||
<Class name="~.*\.Manifest\$.*"/>
|
||||
</Match>
|
||||
<Match>
|
||||
<!-- ignore concrete check groups -->
|
||||
<Bug code="DP"/>
|
||||
</Match>
|
||||
<Match>
|
||||
<!-- ignore concrete checks -->
|
||||
<Bug pattern="BC_UNCONFIRMED_CAST_OF_RETURN_VALUE, NP_UNWRITTEN_FIELD, UWF_NULL_FIELD, UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR, PZLA_PREFER_ZERO_LENGTH_ARRAYS, EI_EXPOSE_REP, EI_EXPOSE_REP2, REC_CATCH_EXCEPTION, EQ_COMPARETO_USE_OBJECT_EQUALS, BC_UNCONFIRMED_CAST, EQ_DOESNT_OVERRIDE_EQUALS, BC_IMPOSSIBLE_CAST" />
|
||||
</Match>
|
||||
<Match>
|
||||
<Bug code="UPM" />
|
||||
<Class name="~.*\$\$Lambda\$.*"/>
|
||||
</Match>
|
||||
|
||||
</FindBugsFilter>
|
||||
|
|
@ -0,0 +1,407 @@
|
|||
apply plugin: 'checkstyle'
|
||||
apply plugin: 'pmd'
|
||||
apply plugin: 'cpd'
|
||||
|
||||
def getBinaries
|
||||
def getSources
|
||||
def getCpdTask
|
||||
def getPmdTask
|
||||
def getLintTasks
|
||||
def getCheckstyleTask
|
||||
|
||||
def getStaticAnalysisTasks
|
||||
|
||||
def appendError
|
||||
def appendCheckstyleErrors
|
||||
def appendPmdErrors
|
||||
def appendCpdErrors
|
||||
def appendLintErrors
|
||||
def normilizeFileUrl
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url "http://dl.bintray.com/touchin/touchin-tools"
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
pngtastic
|
||||
}
|
||||
|
||||
dependencies {
|
||||
pmd 'net.sourceforge.pmd:pmd-core:5.4.0'
|
||||
pmd 'net.sourceforge.pmd:pmd-java:5.4.0'
|
||||
|
||||
checkstyle 'ru.touchin:checkstyle:6.15-fork'
|
||||
|
||||
pngtastic 'com.github.depsypher:pngtastic:1.2'
|
||||
}
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.compilerArgs <<
|
||||
"-Xlint:cast" <<
|
||||
"-Xlint:divzero" <<
|
||||
"-Xlint:empty" <<
|
||||
"-Xlint:deprecation" <<
|
||||
"-Xlint:finally" <<
|
||||
"-Xlint:overrides" <<
|
||||
"-Xlint:path" <<
|
||||
"-Xlint:unchecked" <<
|
||||
"-Werror"
|
||||
}
|
||||
|
||||
task staticAnalysis {
|
||||
def excludes = rootProject.extensions.findByName("staticAnalysisExcludes");
|
||||
dependsOn getStaticAnalysisTasks(getSources(excludes), getBinaries(excludes))
|
||||
|
||||
doFirst {
|
||||
StringBuilder fullReport = new StringBuilder()
|
||||
|
||||
fullReport.append("<table cellpadding='10px' border='2px' cellspacing='0px' cols='4'>");
|
||||
|
||||
StringBuilder consoleReport = new StringBuilder()
|
||||
consoleReport.append("STATIC ANALYSIS RESULTS:")
|
||||
def count = 0
|
||||
|
||||
def previousCount = count
|
||||
count = appendCpdErrors(fullReport, count, new File("${project.buildDir}/reports/cpd_${project.name}.xml"))
|
||||
if (count - previousCount > 0) {
|
||||
consoleReport.append("\n\u001B[31mCPD: FAILED (" + (count - previousCount) + " errors)\u001B[0m " +
|
||||
normilizeFileUrl("file://${project.buildDir}/reports/cpd_${project.name}.xml"))
|
||||
} else {
|
||||
consoleReport.append("\n\u001B[32mCPD: PASSED\u001B[0m")
|
||||
}
|
||||
|
||||
previousCount = count
|
||||
count = appendPmdErrors(fullReport, count, new File("${project.buildDir}/reports/pmd_${project.name}.xml"))
|
||||
if (count - previousCount > 0) {
|
||||
consoleReport.append("\n\u001B[31mPMD: FAILED (" + (count - previousCount) + " errors)\u001B[0m " +
|
||||
normilizeFileUrl("file://${project.buildDir}/reports/pmd_${project.name}.html"))
|
||||
} else {
|
||||
consoleReport.append("\n\u001B[32mPMD: PASSED\u001B[0m")
|
||||
}
|
||||
|
||||
previousCount = count
|
||||
count = appendLintErrors(fullReport, count, new File("${project.buildDir}/reports/lint_${project.name}.xml"))
|
||||
if (count - previousCount > 0) {
|
||||
consoleReport.append("\n\u001B[31mLint: FAILED (" + (count - previousCount) + " errors)\u001B[0m " +
|
||||
normilizeFileUrl("file://${project.buildDir}/reports/lint_${project.name}.html"))
|
||||
} else {
|
||||
consoleReport.append("\n\u001B[32mLint: PASSED\u001B[0m")
|
||||
}
|
||||
|
||||
previousCount = count
|
||||
count = appendCheckstyleErrors(fullReport, count, new File("${project.buildDir}/reports/checkstyle_${project.name}.xml"))
|
||||
if (count - previousCount > 0) {
|
||||
consoleReport.append("\n\u001B[31mCheckstyle: FAILED (" + (count - previousCount) + " errors)\u001B[0m " +
|
||||
normilizeFileUrl("file://${project.buildDir}/reports/checkstyle_${project.name}.xml"))
|
||||
} else {
|
||||
consoleReport.append("\n\u001B[32mCheckstyle: PASSED\u001B[0m")
|
||||
}
|
||||
|
||||
fullReport.append("\n</table>\n");
|
||||
fullReport.append("<script>\n" +
|
||||
"\tfunction visitPage(file, line) {\n" +
|
||||
"\t\tfor (port = 63330; port < 63340; port++) {\n" +
|
||||
"\t\t\tvar theUrl='http://127.0.0.1:' + port + '/file?file=' + file + '&line=' + line;\n" +
|
||||
"\t\t\tvar xmlHttp = new XMLHttpRequest();\n" +
|
||||
"\t\t\txmlHttp.open('GET', theUrl, true);\n" +
|
||||
"\t\t\txmlHttp.send(null);\n" +
|
||||
"\t\t}\n" +
|
||||
"\t}\n" +
|
||||
"</script>");
|
||||
|
||||
File fullReportFile = new File("${project.buildDir}/reports/full_report.html")
|
||||
fullReportFile.write(fullReport.toString());
|
||||
|
||||
if (count > 0) {
|
||||
consoleReport.append("\n\u001B[31mOverall: FAILED (" + count + " errors)\u001B[0m "
|
||||
+ normilizeFileUrl("file://${project.buildDir}/reports/full_report.html"))
|
||||
throw new Exception(consoleReport.toString())
|
||||
} else {
|
||||
consoleReport.append("\n\u001B[32mOverall: PASSED\u001B[0m")
|
||||
println(consoleReport.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task optimizePng {
|
||||
doFirst {
|
||||
def jarArgs = new ArrayList<String>()
|
||||
jarArgs.add(configurations.pngtastic.asPath)
|
||||
def relatedPathIndex = "${rootDir}".length() + 1
|
||||
for (def file : fileTree(dir: "${rootDir}", include: '**/src/**/res/drawable**/*.png')) {
|
||||
jarArgs.add(file.absolutePath.substring(relatedPathIndex))
|
||||
}
|
||||
javaexec { main = "-jar"; args = jarArgs; workingDir = file("${rootDir}") }
|
||||
}
|
||||
}
|
||||
|
||||
normilizeFileUrl = { url ->
|
||||
return url.replace("\\", "/");
|
||||
}
|
||||
|
||||
appendError = { report, number, analyzer, file, line, errorId, errorLink, description ->
|
||||
report.append("\n\t<tr>")
|
||||
|
||||
report.append("\n\t\t<td>" + number + "</td>")
|
||||
|
||||
report.append("\n\t\t<td>" + analyzer + "</td>")
|
||||
|
||||
//TODO: file fb
|
||||
report.append("\n\t\t<td>")
|
||||
if (!analyzer.equals("Lint")) {
|
||||
report.append("\n\t\t\t<a target='_blank' href='" + errorLink + "'>" + description + " (" + errorId + ")</a>")
|
||||
} else {
|
||||
report.append("\n\t\t\t<a href='javascript:alert(\"" + errorLink.replace("'", "'") + "\")'>" + description + " (" + errorId + ")</a>")
|
||||
}
|
||||
report.append("\n\t\t</td>")
|
||||
|
||||
def indexOfSrc = file.indexOf("src")
|
||||
def deeplink = (indexOfSrc > 0 ? file.substring(indexOfSrc) : file).replace('\\', '/')
|
||||
report.append("\n\t\t<td>")
|
||||
report.append("\n\t\t\t<a href='javascript:visitPage(\"" + deeplink + "\", " + line + ")'>" + file + ":" + line + "</a>")
|
||||
report.append("\n\t\t</td>")
|
||||
|
||||
report.append("\n\t</tr>")
|
||||
println("\n\u001B[31m" + number + " " + analyzer + ": " + description + " (" + errorId + ")\n\tat " + file + ":" + line + "\u001B[0m")
|
||||
}
|
||||
|
||||
appendCheckstyleErrors = { report, count, checkstyleFile ->
|
||||
def rootNode = new XmlParser().parse(checkstyleFile)
|
||||
for (def fileNode : rootNode.children()) {
|
||||
if (!fileNode.name().equals("file")) {
|
||||
continue
|
||||
}
|
||||
|
||||
for (def errorNode : fileNode.children()) {
|
||||
if (!errorNode.name().equals("error")) {
|
||||
continue
|
||||
}
|
||||
count++;
|
||||
|
||||
def error = errorNode.attribute("source")
|
||||
def link = "http://checkstyle.sourceforge.net/apidocs/" + error.replace('.', '/') + ".html"
|
||||
appendError(report, count, "Checkstyle", fileNode.attribute("name"), errorNode.attribute("line"), error, link, errorNode.attribute("message"))
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
appendPmdErrors = { report, count, pmdFile ->
|
||||
def rootNode = new XmlParser().parse(pmdFile)
|
||||
for (def fileNode : rootNode.children()) {
|
||||
if (!fileNode.name().equals("file")) {
|
||||
continue
|
||||
}
|
||||
|
||||
for (def errorNode : fileNode.children()) {
|
||||
if (!errorNode.name().equals("violation")) {
|
||||
continue;
|
||||
}
|
||||
count++;
|
||||
|
||||
appendError(report, count, "PMD", fileNode.attribute("name"), errorNode.attribute("beginline"),
|
||||
errorNode.attribute("rule").trim(), errorNode.attribute("externalInfoUrl").trim(), errorNode.text().trim())
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
appendCpdErrors = { report, count, cpdFile ->
|
||||
def rootNode = new XmlParser().parse(cpdFile)
|
||||
for (def duplicationNode : rootNode.children()) {
|
||||
if (!duplicationNode.name().equals("duplication")) {
|
||||
continue
|
||||
}
|
||||
count++;
|
||||
|
||||
report.append("\n\t<tr>")
|
||||
|
||||
report.append("\n\t\t<td>" + count + "</td>")
|
||||
|
||||
report.append("\n\t\t<td>CPD</td>")
|
||||
|
||||
def fragment = "<b>Code duplication:</b></br></br>"
|
||||
def links = ""
|
||||
def duplicationIndex = 0
|
||||
String duplicationPoints = "";
|
||||
for (def filePointNode : duplicationNode.children()) {
|
||||
if (filePointNode.name().equals("file")) {
|
||||
def file = filePointNode.attribute("path")
|
||||
def line = filePointNode.attribute("line");
|
||||
def indexOfSrc = file.indexOf("src")
|
||||
def deeplink = (indexOfSrc > 0 ? file.substring(indexOfSrc) : file).replace('\\', '/')
|
||||
if (duplicationIndex > 0) {
|
||||
links += "\n\t\t\t</br></br>"
|
||||
}
|
||||
links += "Code fragment " + (duplicationIndex + 1) + "</br>"
|
||||
links += "\n\t\t\t<a href='javascript:visitPage(\"" + deeplink + "\", " + line + ")'>" + file + ":" + line + "</a>"
|
||||
duplicationPoints += "\n\tat " + file + ":" + line
|
||||
duplicationIndex++
|
||||
} else if (filePointNode.name().equals("codefragment")) {
|
||||
fragment += filePointNode.text().replace("\n", "</br>").replace(" ", " ")
|
||||
}
|
||||
}
|
||||
report.append("\n\t\t<td>" + fragment + "\n\t\t</td>")
|
||||
|
||||
report.append("\n\t\t<td>" + links + "\n\t\t</td>")
|
||||
|
||||
report.append("\n\t</tr>")
|
||||
println("\u001B[31m" + count + " CPD: code duplication" + duplicationPoints + "\u001B[0m")
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
appendLintErrors = { report, count, lintFile ->
|
||||
def rootNode = new XmlParser().parse(lintFile)
|
||||
for (def issueNode : rootNode.children()) {
|
||||
if (!issueNode.name().equals("issue")
|
||||
|| !issueNode.attribute("severity").equals("Error")) {
|
||||
continue
|
||||
}
|
||||
for (def locationNode : issueNode.children()) {
|
||||
if (!locationNode.name().equals("location")) {
|
||||
continue
|
||||
}
|
||||
count++;
|
||||
appendError(report, count, "Lint", locationNode.attribute("file"), locationNode.attribute("line"),
|
||||
issueNode.attribute("id"), issueNode.attribute("explanation"), issueNode.attribute("message"))
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
getBinaries = { excludes ->
|
||||
def binaries = new ArrayList<String>()
|
||||
for (def project : rootProject.subprojects) {
|
||||
if (!project.subprojects.isEmpty() || (excludes != null && excludes.contains(project.path))) {
|
||||
continue
|
||||
}
|
||||
binaries.add("${project.projectDir}/build/intermediates/classes")
|
||||
}
|
||||
return binaries
|
||||
}
|
||||
|
||||
getSources = { excludes ->
|
||||
def sources = new ArrayList<String>()
|
||||
for (def project : rootProject.subprojects) {
|
||||
if (!project.subprojects.isEmpty() || (excludes != null && excludes.contains(project.path))) {
|
||||
continue
|
||||
}
|
||||
|
||||
def sourcesDirectory = new File(project.projectDir.path, 'src')
|
||||
if (!sourcesDirectory.exists() || !sourcesDirectory.isDirectory()) {
|
||||
continue
|
||||
}
|
||||
|
||||
for (def sourceFlavorDirectory : sourcesDirectory.listFiles()) {
|
||||
def sourceSetDirectory = new File(sourceFlavorDirectory.path, 'java');
|
||||
if (!sourceSetDirectory.exists() || !sourceSetDirectory.isDirectory()) {
|
||||
continue
|
||||
}
|
||||
sources.add(sourceSetDirectory.absolutePath)
|
||||
}
|
||||
}
|
||||
return sources
|
||||
}
|
||||
|
||||
getCpdTask = { sources ->
|
||||
def taskName = "cpd_${project.name}"
|
||||
tasks.create(taskName, tasks.findByName('cpdCheck').getClass().getSuperclass()) {
|
||||
minimumTokenCount = 60
|
||||
source = files(sources)
|
||||
ignoreFailures = true
|
||||
reports {
|
||||
xml {
|
||||
enabled = true
|
||||
destination "${project.buildDir}/reports/${taskName}.xml"
|
||||
}
|
||||
}
|
||||
}
|
||||
return taskName
|
||||
}
|
||||
|
||||
getPmdTask = { sources ->
|
||||
def taskName = "pmd_${project.name}"
|
||||
tasks.create(taskName, Pmd) {
|
||||
pmdClasspath = configurations.pmd.asFileTree
|
||||
ruleSetFiles = files("${rootDir}/libraries/BuildScripts/pmd/rulesets/java/android.xml")
|
||||
ruleSets = []
|
||||
source files(sources)
|
||||
ignoreFailures = true
|
||||
reports {
|
||||
html {
|
||||
enabled = true
|
||||
destination "${project.buildDir}/reports/${taskName}.html"
|
||||
}
|
||||
xml {
|
||||
enabled = true
|
||||
destination "${project.buildDir}/reports/${taskName}.xml"
|
||||
}
|
||||
}
|
||||
}
|
||||
return taskName
|
||||
}
|
||||
|
||||
getCheckstyleTask = { sources ->
|
||||
def taskName = "checkstyle_${project.name}"
|
||||
def compileReleaseTask = tasks.matching {
|
||||
it.getName().contains("compile") && it.getName().contains("Release") && it.getName().contains("Java") && !it.getName().contains("UnitTest")
|
||||
}.last()
|
||||
tasks.create(taskName, Checkstyle) {
|
||||
ignoreFailures = true
|
||||
showViolations = false
|
||||
source files(sources)
|
||||
configFile file("${rootDir}/libraries/BuildScripts/checkstyle/configuration/google_checks.xml")
|
||||
checkstyleClasspath = configurations.checkstyle.asFileTree
|
||||
classpath = files(System.getenv("ANDROID_HOME") + "/platforms/" + android.compileSdkVersion + "/android.jar") +
|
||||
files(System.properties.'java.home' + "/lib/rt.jar") +
|
||||
compileReleaseTask.classpath
|
||||
reports {
|
||||
xml {
|
||||
enabled = true
|
||||
destination "${project.buildDir}/reports/${taskName}.xml"
|
||||
}
|
||||
}
|
||||
}
|
||||
return taskName
|
||||
}
|
||||
|
||||
getLintTasks = {
|
||||
def lintTaskNames = new ArrayList<String>()
|
||||
|
||||
def lintReleaseTask = tasks.matching {
|
||||
it.getName().contains("lint") && it.getName().contains("Release")
|
||||
}.first();
|
||||
//TODO return on jack lintReleaseTask.dependsOn.clear()
|
||||
lintTaskNames.add(lintReleaseTask.getName())
|
||||
|
||||
def lintDebugTask = tasks.matching {
|
||||
it.getName().contains("lint") && it.getName().contains("Debug")
|
||||
}.first();
|
||||
//TODO return on jack lintDebugTask.dependsOn.clear()
|
||||
lintTaskNames.add(lintDebugTask.getName())
|
||||
|
||||
android.lintOptions.abortOnError = false
|
||||
android.lintOptions.checkAllWarnings = true
|
||||
android.lintOptions.warningsAsErrors = false
|
||||
android.lintOptions.xmlReport = true
|
||||
android.lintOptions.xmlOutput = file("${project.buildDir}/reports/lint_${project.name}.xml")
|
||||
android.lintOptions.htmlReport = true
|
||||
android.lintOptions.htmlOutput = file("${project.buildDir}/reports/lint_${project.name}.html")
|
||||
android.lintOptions.lintConfig = file("${rootDir}/libraries/BuildScripts/lint/lint.xml")
|
||||
return lintTaskNames
|
||||
}
|
||||
|
||||
getStaticAnalysisTasks = { sources, binaries ->
|
||||
def tasksNames = new ArrayList<String>()
|
||||
tasksNames.add(getCpdTask(sources))
|
||||
tasksNames.add(getCheckstyleTask(sources))
|
||||
tasksNames.add(getPmdTask(sources))
|
||||
tasksNames.addAll(getLintTasks())
|
||||
return tasksNames
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<lint>
|
||||
|
||||
<issue id="InvalidPackage" severity="error">
|
||||
<ignore regexp="Invalid package reference in library.*not included in Android.*java.*"/>
|
||||
</issue>
|
||||
<!-- todo: use new versions of fresco when problem with fbcore not found -->
|
||||
<issue id="NewerVersionAvailable" severity="error">
|
||||
<ignore regexp="A newer version of com.facebook.fresco:fresco than .+ is available: .+"/>
|
||||
</issue>
|
||||
<issue id="NewerVersionAvailable" severity="error">
|
||||
<ignore regexp="A newer version of io.socket:socket.io-client than .+ is available: .+"/>
|
||||
</issue>
|
||||
<issue id="NewerVersionAvailable" severity="error">
|
||||
<ignore regexp="A newer version of de.ruedigermoeller:fst than .+ is available: .+"/>
|
||||
</issue>
|
||||
|
||||
<issue id="AdapterViewChildren" severity="error"/>
|
||||
<issue id="AddJavascriptInterface" severity="info"/>
|
||||
<issue id="AllowBackup" severity="error"/>
|
||||
<issue id="AlwaysShowAction" severity="error"/>
|
||||
<issue id="AppCompatMethod" severity="error"/>
|
||||
<issue id="AppIndexingApiWarning" severity="error"/>
|
||||
<issue id="Assert" severity="error"/>
|
||||
<issue id="CommitPrefEdits" severity="error"/>
|
||||
<issue id="CommitTransaction" severity="error"/>
|
||||
<issue id="CustomViewStyleable" severity="error"/>
|
||||
<issue id="CutPasteId" severity="error"/>
|
||||
<issue id="Deprecated" severity="error"/>
|
||||
<issue id="DeviceAdmin" severity="error"/>
|
||||
<issue id="DisableBaselineAlignment" severity="error"/>
|
||||
<issue id="DrawAllocation" severity="warning"/>
|
||||
<issue id="DuplicateIncludedIds" severity="error"/>
|
||||
<issue id="DuplicateUsesFeature" severity="error"/>
|
||||
<issue id="ExportedContentProvider" severity="error"/>
|
||||
<issue id="ExportedReceiver" severity="error"/>
|
||||
<issue id="ExportedService" severity="error"/>
|
||||
<issue id="ExtraText" severity="error"/>
|
||||
<issue id="GetInstance" severity="error"/>
|
||||
<issue id="GifUsage" severity="error"/>
|
||||
<issue id="GradleDependency" severity="error"/>
|
||||
<issue id="GradleDeprecated" severity="error"/>
|
||||
<issue id="GradleDynamicVersion" severity="error"/>
|
||||
<issue id="GradleOverrides" severity="error"/>
|
||||
<issue id="GradlePath" severity="warning"/>
|
||||
<issue id="GrantAllUris" severity="error"/>
|
||||
<issue id="HandlerLeak" severity="error"/>
|
||||
<issue id="HardcodedText" severity="error"/>
|
||||
<issue id="IconColors" severity="warning"/>
|
||||
<issue id="IconDensities" severity="warning"/>
|
||||
<issue id="IconDipSize" severity="error"/>
|
||||
<issue id="IconDuplicates" severity="error"/>
|
||||
<issue id="IconDuplicatesConfig" severity="error"/>
|
||||
<issue id="IconExtension" severity="error"/>
|
||||
<issue id="IconLocation" severity="error"/>
|
||||
<issue id="IconMixedNinePatch" severity="error"/>
|
||||
<issue id="IconNoDpi" severity="error"/>
|
||||
<issue id="IconXmlAndPng" severity="error"/>
|
||||
<issue id="IllegalResourceRef" severity="error"/>
|
||||
<issue id="InOrMmUsage" severity="error"/>
|
||||
<issue id="InconsistentArrays" severity="error"/>
|
||||
<issue id="InefficientWeight" severity="warning"/>
|
||||
<issue id="InflateParams" severity="warning"/>
|
||||
<issue id="InnerclassSeparator" severity="error"/>
|
||||
<issue id="LocaleFolder" severity="error"/>
|
||||
<issue id="LogConditional" severity="error"/>
|
||||
<issue id="ManifestOrder" severity="error"/>
|
||||
<issue id="MipmapIcons" severity="error"/>
|
||||
<issue id="MissingApplicationIcon" severity="error"/>
|
||||
<issue id="MissingId" severity="error"/>
|
||||
<issue id="MissingVersion" severity="error"/>
|
||||
<issue id="NestedWeights" severity="warning"/>
|
||||
<issue id="ObsoleteLayoutParam" severity="error"/>
|
||||
<issue id="OldTargetApi" severity="error"/>
|
||||
<issue id="PackageManagerGetSignatures" severity="error"/>
|
||||
<issue id="PrivateResource" severity="error"/>
|
||||
<issue id="ProguardSplit" severity="error"/>
|
||||
<issue id="PxUsage" severity="error"/>
|
||||
<issue id="Recycle" severity="error"/>
|
||||
<issue id="Registered" severity="error"/>
|
||||
<issue id="RtlEnabled" severity="error"/>
|
||||
<issue id="SQLiteString" severity="error"/>
|
||||
<issue id="ScrollViewCount" severity="error"/>
|
||||
<issue id="ScrollViewSize" severity="error"/>
|
||||
<issue id="SdCardPath" severity="error"/>
|
||||
<issue id="ShortAlarm" severity="warning"/>
|
||||
<issue id="ShowToast" severity="error"/>
|
||||
<issue id="SignatureOrSystemPermissions" severity="error"/>
|
||||
<issue id="SimpleDateFormat" severity="error"/>
|
||||
<issue id="SpUsage" severity="error"/>
|
||||
<issue id="StateListReachable" severity="error"/>
|
||||
<issue id="SuspiciousImport" severity="error"/>
|
||||
<issue id="TextFields" severity="error"/>
|
||||
<issue id="TextViewEdits" severity="error"/>
|
||||
<issue id="TooDeepLayout" severity="warning"/>
|
||||
<issue id="TooManyViews" severity="warning"/>
|
||||
<issue id="TypographyDashes" severity="warning"/>
|
||||
<issue id="TypographyEllipsis" severity="error"/>
|
||||
<issue id="UnknownIdInLayout" severity="error"/>
|
||||
<issue id="UnlocalizedSms" severity="error"/>
|
||||
<issue id="UnusedIds" severity="error"/>
|
||||
<issue id="UseAlpha2" severity="error"/>
|
||||
<issue id="UseSparseArrays" severity="warning"/>
|
||||
<issue id="UseValueOf" severity="error"/>
|
||||
<issue id="UsesMinSdkAttributes" severity="error"/>
|
||||
<issue id="UsingHttp" severity="warning"/>
|
||||
<issue id="WorldReadableFiles" severity="warning"/>
|
||||
<issue id="WorldWriteableFiles" severity="warning"/>
|
||||
<issue id="WrongRegion" severity="warning"/>
|
||||
|
||||
<!-- DISABLE RULES BELOW -->
|
||||
<issue id="UnusedIds" severity="ignore"/>
|
||||
<issue id="ButtonCase" severity="ignore"/>
|
||||
<issue id="ButtonOrder" severity="ignore"/>
|
||||
<issue id="ButtonStyle" severity="ignore"/>
|
||||
<issue id="ContentDescription" severity="ignore"/>
|
||||
<issue id="ExportedPreferenceActivity" severity="ignore"/>
|
||||
<issue id="IconLauncherShape" severity="ignore"/>
|
||||
<issue id="IconMissingDensityFolder" severity="ignore"/>
|
||||
<issue id="InconsistentLayout" severity="ignore"/>
|
||||
<issue id="LabelFor" severity="ignore"/>
|
||||
<issue id="MissingTranslation" severity="ignore"/>
|
||||
<issue id="NestedScrolling" severity="ignore"/>
|
||||
<issue id="MergeRootFrame" severity="ignore"/>
|
||||
<issue id="NewApi" severity="ignore"/>
|
||||
<issue id="Overdraw" severity="ignore"/>
|
||||
<issue id="PluralsCandidate" severity="ignore"/>
|
||||
<issue id="RelativeOverlap" severity="ignore"/>
|
||||
<issue id="RtlHardcoded" severity="ignore"/>
|
||||
<issue id="RtlSymmetry" severity="ignore"/>
|
||||
<issue id="SmallSp" severity="ignore"/>
|
||||
<issue id="StringFormatCount" severity="ignore"/>
|
||||
<issue id="TypographyFractions" severity="ignore"/>
|
||||
<issue id="Typos" severity="ignore"/>
|
||||
<issue id="UnusedQuantity" severity="ignore"/>
|
||||
<issue id="UnusedResources" severity="ignore"/>
|
||||
<issue id="UseCompoundDrawables" severity="ignore"/>
|
||||
<issue id="UselessLeaf" severity="ignore"/>
|
||||
<issue id="UselessParent" severity="ignore"/>
|
||||
<issue id="ViewConstructor" severity="ignore"/>
|
||||
<issue id="ViewHolder" severity="ignore"/>
|
||||
<issue id="WebViewLayout" severity="ignore"/>
|
||||
|
||||
</lint>
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<ruleset name="All Java Rules"
|
||||
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
|
||||
<description>Every Java Rule in PMD</description>
|
||||
|
||||
<rule ref="rulesets/java/android.xml"/>
|
||||
<rule ref="rulesets/java/basic.xml">
|
||||
<exclude name="SimplifiedTernary"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/braces.xml"/>
|
||||
<rule ref="rulesets/java/clone.xml"/>
|
||||
<rule ref="rulesets/java/codesize.xml"/>
|
||||
<rule ref="rulesets/java/codesize.xml/TooManyMethods">
|
||||
<properties>
|
||||
<property name="maxmethods" value="20"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/comments.xml">
|
||||
<exclude name="CommentSize"/>
|
||||
<exclude name="CommentRequired"/>
|
||||
<exclude name="CommentDefaultAccessModifier"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/controversial.xml">
|
||||
<exclude name="AtLeastOneConstructor"/>
|
||||
<exclude name="OnlyOneReturn"/>
|
||||
<exclude name="UseConcurrentHashMap"/>
|
||||
<exclude name="NullAssignment"/>
|
||||
<exclude name="DataflowAnomalyAnalysis"/>
|
||||
<exclude name="AvoidFinalLocalVariable"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/controversial.xml/AvoidLiteralsInIfCondition">
|
||||
<properties>
|
||||
<property name="ignoreMagicNumbers" value="-1,0,1"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/coupling.xml">
|
||||
<exclude name="LoosePackageCoupling"/>
|
||||
<exclude name="LawOfDemeter"/>
|
||||
<exclude name="LooseCoupling"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/coupling.xml/ExcessiveImports">
|
||||
<properties>
|
||||
<property name="minimum" value="50"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/design.xml">
|
||||
<exclude name="GodClass"/>
|
||||
<exclude name="ConfusingTernary"/>
|
||||
<exclude name="ReturnEmptyArrayRatherThanNull"/>
|
||||
<exclude name="FieldDeclarationsShouldBeAtStartOfClass"/>
|
||||
<exclude name="EmptyMethodInAbstractClassShouldBeAbstract"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/empty.xml"/>
|
||||
<rule ref="rulesets/java/empty.xml/EmptyCatchBlock">
|
||||
<properties>
|
||||
<property name="allowCommentedBlocks" value="true"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/finalizers.xml"/>
|
||||
<rule ref="rulesets/java/imports.xml"/>
|
||||
<rule ref="rulesets/java/j2ee.xml">
|
||||
<exclude name="DoNotUseThreads"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/javabeans.xml">
|
||||
<exclude name="BeanMembersShouldSerialize"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/junit.xml"/>
|
||||
<rule ref="rulesets/java/logging-jakarta-commons.xml"/>
|
||||
<rule ref="rulesets/java/logging-java.xml"/>
|
||||
<rule ref="rulesets/java/migrating.xml"/>
|
||||
<rule ref="rulesets/java/naming.xml">
|
||||
<exclude name="SuspiciousEqualsMethodName"/>
|
||||
<exclude name="AbstractNaming"/>
|
||||
<exclude name="ShortVariable"/>
|
||||
<exclude name="LongVariable"/>
|
||||
<exclude name="GenericsNaming"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/naming.xml/ShortClassName">
|
||||
<properties>
|
||||
<property name="minimum" value="4"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/optimizations.xml">
|
||||
<exclude name="AvoidInstantiatingObjectsInLoops"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/strictexception.xml">
|
||||
<exclude name="AvoidCatchingGenericException"/>
|
||||
<exclude name="SignatureDeclareThrowsException"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/strings.xml"/>
|
||||
<rule ref="rulesets/java/sunsecure.xml">
|
||||
<exclude name="MethodReturnsInternalArray"/>
|
||||
<exclude name="ArrayIsStoredDirectly"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/typeresolution.xml">
|
||||
<exclude name="SignatureDeclareThrowsException"/>
|
||||
<exclude name="LooseCoupling"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/unnecessary.xml">
|
||||
<exclude name="UselessParentheses"/>
|
||||
</rule>
|
||||
<rule ref="rulesets/java/unusedcode.xml"/>
|
||||
</ruleset>
|
||||
Loading…
Reference in New Issue