Initial commit

This commit is contained in:
Vsevolod Ivanov 2016-06-21 19:30:09 +03:00
commit 92cca73cfc
7 changed files with 914 additions and 0 deletions

1
README.md Normal file
View File

@ -0,0 +1 @@
# BuildScripts

View File

@ -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);
?>

View File

@ -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>

View File

@ -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>

View File

@ -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("'", "&apos;") + "\")'>" + 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(" ", "&nbsp;")
}
}
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
}

144
lint/lint.xml Normal file
View File

@ -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>

View File

@ -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>