From 1dd879f255ea9dc5afb41f3338e7c759a03b7300 Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Sun, 28 Jun 2020 23:14:29 +0300 Subject: [PATCH 01/13] update api gen version --- gradle/apiGenerator.gradle | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gradle/apiGenerator.gradle b/gradle/apiGenerator.gradle index 12eac76..5f3435c 100644 --- a/gradle/apiGenerator.gradle +++ b/gradle/apiGenerator.gradle @@ -12,10 +12,10 @@ configurations { } dependencies { - apigenerator 'ru.touchin:api-generator:1.4.0-beta1' + apigenerator 'ru.touchin:api-generator:1.4.0-beta2' } -android.applicationVariants.all { variant -> +android.libraryVariants.all { variant -> final File generatedModelsDirectory = new File("${project.buildDir}/generated/source/models/${variant.dirName}") def generateJsonModelsTask = tasks.create("apiGenerator${variant.name}") doLast { @@ -26,9 +26,11 @@ android.applicationVariants.all { variant -> configurations.apigenerator.asPath, "generate-client-code", "--output-language", - "JAVA", + "KOTLIN", "--specification-path", rootProject.extensions.findByName("pathToApiSchemes"), + "--kotlin-methods-generation-mode", + "coroutines", "--output-path", "${generatedModelsDirectory.path}", "--package-name", From 86702efd508a75a3882ec45e54630ec4d0a0f6bc Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Mon, 29 Jun 2020 00:58:20 +0300 Subject: [PATCH 02/13] add to string generator root path for multimodule project --- gradle/stringGenerator.gradle | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gradle/stringGenerator.gradle b/gradle/stringGenerator.gradle index a05b155..374ab12 100644 --- a/gradle/stringGenerator.gradle +++ b/gradle/stringGenerator.gradle @@ -2,11 +2,11 @@ import groovy.json.JsonSlurper import groovy.xml.MarkupBuilder task stringGenerator { - generate(android.languageMap) + generate(android.languageMap, android.rootPath ?: "app") println("Strings generated!") } -private def generate(Map sources) { +private def generate(Map sources, String rootPath) { if (sources == null || sources.isEmpty()) { throw new IOException("languageMap can't be null or empty") } @@ -31,7 +31,7 @@ private def generate(Map sources) { } } - def stringsFile = getFile(key, key == defaultLang) + def stringsFile = getFile(key, key == defaultLang, rootPath) stringsFile.write(sw.toString(), "UTF-8") } } @@ -69,15 +69,15 @@ private static Map getJsonsMap(Map sources) { } } -private static File getFile(String key, boolean defaultLang) { +private static File getFile(String key, boolean defaultLang, String rootPath) { if (defaultLang) { - return new File("app/src/main/res/values/strings.xml") + return new File("${rootPath}/src/main/res/values/strings.xml") } else { - def directory = new File("app/src/main/res/values-$key") + def directory = new File("${rootPath}/src/main/res/values-$key") if (!directory.exists()) { directory.mkdir() } - return new File("app/src/main/res/values-$key/strings.xml") + return new File("${rootPath}/src/main/res/values-$key/strings.xml") } } From 7850b7f0cdd5d261e532d265b33464a9140a6d45 Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Mon, 29 Jun 2020 01:19:47 +0300 Subject: [PATCH 03/13] fix correct name for coroutines --- gradle/apiGenerator.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/apiGenerator.gradle b/gradle/apiGenerator.gradle index 5f3435c..9a094c3 100644 --- a/gradle/apiGenerator.gradle +++ b/gradle/apiGenerator.gradle @@ -30,7 +30,7 @@ android.libraryVariants.all { variant -> "--specification-path", rootProject.extensions.findByName("pathToApiSchemes"), "--kotlin-methods-generation-mode", - "coroutines", + "COROUTINE", "--output-path", "${generatedModelsDirectory.path}", "--package-name", From e3e730c762fc56717e8763313ca7abdd9bc0bf79 Mon Sep 17 00:00:00 2001 From: Vladimir Date: Tue, 7 Jul 2020 18:51:13 +0300 Subject: [PATCH 04/13] updated api gen version --- gradle/apiGenerator.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/apiGenerator.gradle b/gradle/apiGenerator.gradle index 9a094c3..fc9dae3 100644 --- a/gradle/apiGenerator.gradle +++ b/gradle/apiGenerator.gradle @@ -12,7 +12,7 @@ configurations { } dependencies { - apigenerator 'ru.touchin:api-generator:1.4.0-beta2' + apigenerator 'ru.touchin:api-generator:1.4.0-beta3' } android.libraryVariants.all { variant -> From 1b444a458208831921b3b5bd90361f225569881d Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Wed, 19 Aug 2020 17:06:08 +0300 Subject: [PATCH 05/13] move apigen and static analysis scripts to plugins. removed extra files --- checkstyle/configuration/google_checks.xml | 210 ----------- .../configuration/touchin_checkstyle.xml | 339 ------------------ findbugs/filters/findbugs-filter.xml | 23 -- gradle/apiGenerator.gradle | 44 --- gradle/apiGeneratorKotlinServer.gradle | 38 -- gradle/commonStaticAnalysis.gradle | 233 ------------ gradle/plugins/.gitignore | 19 + gradle/plugins/build.gradle.kts | 52 +++ gradle/plugins/settings.gradle.kts | 0 .../java/apigen/ApiGeneratorAndroidPlugin.kt | 37 ++ .../java/apigen/ApiGeneratorBackendPlugin.kt | 19 + .../main/java/apigen/ApiGeneratorExtension.kt | 22 ++ .../main/java/apigen/ApiGeneratorPlugin.kt | 76 ++++ .../errors/AndroidLintError.kt | 12 + .../java/static_analysis/errors/CpdError.kt | 12 + .../static_analysis/errors/DetektError.kt | 12 + .../errors/StaticAnalysisError.kt | 5 + .../static_analysis/linters/AndroidLinter.kt | 65 ++++ .../java/static_analysis/linters/CpdLinter.kt | 57 +++ .../static_analysis/linters/DetektLinter.kt | 62 ++++ .../java/static_analysis/linters/Linter.kt | 12 + .../plugins/StaticAnalysisAndroidPlugin.kt | 43 +++ .../plugins/StaticAnalysisBackendPlugin.kt | 21 ++ .../plugins/StaticAnalysisExtension.kt | 6 + .../plugins/StaticAnalysisPlugin.kt | 47 +++ .../java/static_analysis/utils/Extensions.kt | 33 ++ .../static_analysis/utils/ReportGenerator.kt | 52 +++ .../applicationFileNaming.gradle | 0 gradle/{ => scripts}/stringGenerator.gradle | 0 gradle/staticAnalysis.gradle | 166 --------- lint/lint.xml | 272 -------------- pmd/rulesets/java/android.xml | 131 ------- export_src.sh => scripts/export_src.sh | 0 .../detekt-config.yml | 2 +- static_analysis_configs/lint.xml | 273 ++++++++++++++ 35 files changed, 938 insertions(+), 1457 deletions(-) delete mode 100755 checkstyle/configuration/google_checks.xml delete mode 100755 checkstyle/configuration/touchin_checkstyle.xml delete mode 100644 findbugs/filters/findbugs-filter.xml delete mode 100644 gradle/apiGenerator.gradle delete mode 100644 gradle/apiGeneratorKotlinServer.gradle delete mode 100644 gradle/commonStaticAnalysis.gradle create mode 100644 gradle/plugins/.gitignore create mode 100644 gradle/plugins/build.gradle.kts create mode 100644 gradle/plugins/settings.gradle.kts create mode 100644 gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt create mode 100644 gradle/plugins/src/main/java/apigen/ApiGeneratorBackendPlugin.kt create mode 100644 gradle/plugins/src/main/java/apigen/ApiGeneratorExtension.kt create mode 100644 gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/errors/AndroidLintError.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/errors/CpdError.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/errors/DetektError.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/errors/StaticAnalysisError.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/linters/CpdLinter.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/linters/DetektLinter.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/linters/Linter.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisAndroidPlugin.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisBackendPlugin.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisExtension.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisPlugin.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/utils/Extensions.kt create mode 100644 gradle/plugins/src/main/java/static_analysis/utils/ReportGenerator.kt rename gradle/{ => scripts}/applicationFileNaming.gradle (100%) rename gradle/{ => scripts}/stringGenerator.gradle (100%) delete mode 100644 gradle/staticAnalysis.gradle delete mode 100644 lint/lint.xml delete mode 100644 pmd/rulesets/java/android.xml rename export_src.sh => scripts/export_src.sh (100%) rename {kotlin => static_analysis_configs}/detekt-config.yml (99%) create mode 100644 static_analysis_configs/lint.xml diff --git a/checkstyle/configuration/google_checks.xml b/checkstyle/configuration/google_checks.xml deleted file mode 100755 index 441f1af..0000000 --- a/checkstyle/configuration/google_checks.xml +++ /dev/null @@ -1,210 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/checkstyle/configuration/touchin_checkstyle.xml b/checkstyle/configuration/touchin_checkstyle.xml deleted file mode 100755 index b36d47f..0000000 --- a/checkstyle/configuration/touchin_checkstyle.xml +++ /dev/null @@ -1,339 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/findbugs/filters/findbugs-filter.xml b/findbugs/filters/findbugs-filter.xml deleted file mode 100644 index bb462be..0000000 --- a/findbugs/filters/findbugs-filter.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gradle/apiGenerator.gradle b/gradle/apiGenerator.gradle deleted file mode 100644 index fc9dae3..0000000 --- a/gradle/apiGenerator.gradle +++ /dev/null @@ -1,44 +0,0 @@ -repositories { - maven { - url 'https://dl.bintray.com/touchin/touchin-tools' - metadataSources { - artifact() - } - } -} - -configurations { - apigenerator -} - -dependencies { - apigenerator 'ru.touchin:api-generator:1.4.0-beta3' -} - -android.libraryVariants.all { variant -> - final File generatedModelsDirectory = new File("${project.buildDir}/generated/source/models/${variant.dirName}") - - def generateJsonModelsTask = tasks.create("apiGenerator${variant.name}") doLast { - javaexec { - main = "-jar" - workingDir = file("${rootDir}") - args = [ - configurations.apigenerator.asPath, - "generate-client-code", - "--output-language", - "KOTLIN", - "--specification-path", - rootProject.extensions.findByName("pathToApiSchemes"), - "--kotlin-methods-generation-mode", - "COROUTINE", - "--output-path", - "${generatedModelsDirectory.path}", - "--package-name", - "${rootProject.extensions.findByName("applicationId") ?: applicationId}" - ] - } - } - - generateJsonModelsTask.description = 'Generates Java classes for JSON models' - variant.registerJavaGeneratingTask generateJsonModelsTask, generatedModelsDirectory -} diff --git a/gradle/apiGeneratorKotlinServer.gradle b/gradle/apiGeneratorKotlinServer.gradle deleted file mode 100644 index 66676b5..0000000 --- a/gradle/apiGeneratorKotlinServer.gradle +++ /dev/null @@ -1,38 +0,0 @@ -repositories { - maven { - url "https://dl.bintray.com/touchin/touchin-tools" - metadataSources { - artifact() - } - } -} - -configurations { - apigeneratorKotlinServer -} - -dependencies { - apigeneratorKotlinServer 'ru.touchin:api-generator:1.4.0-beta1' -} - -task generateApiModelsKotlinServer doLast { - javaexec { - main = "-jar" - workingDir = file("${rootDir}") - args = [ - configurations.apigeneratorKotlinServer.asPath, - "generate-client-code", - "--output-language", - "KOTLIN_SERVER", - "--specification-path", - rootProject.extensions.findByName("pathToApiSchemes"), - "--output-path", - "${rootDir}/src/main/kotlin", - "--package-name", - rootProject.extensions.findByName("apiPackageName"), - "--recreate_output_dirs", - false - ] - } -} - diff --git a/gradle/commonStaticAnalysis.gradle b/gradle/commonStaticAnalysis.gradle deleted file mode 100644 index b929257..0000000 --- a/gradle/commonStaticAnalysis.gradle +++ /dev/null @@ -1,233 +0,0 @@ -apply plugin: 'cpd' -apply plugin: 'io.gitlab.arturbosch.detekt' - -def getCpdTask -def getLintTask -def getKotlinDetektTasks - -def appendError -def appendCpdErrors -def appendKotlinErrors -def appendLintErrors - -repositories { - maven { url "http://dl.bintray.com/touchin/touchin-tools" } -} - -configurations { - pngtastic -} - -cpd { - skipLexicalErrors = true -} - -import org.apache.tools.ant.taskdefs.condition.Os - -ext.getIdeaFormatTask = { isAndroidProject, sources -> - def ideaPath = System.getenv("IDEA_HOME") - if (ideaPath == null) { - return tasks.create((isAndroidProject ? "android" : "server") + "donothing") - } - return tasks.create((isAndroidProject ? "android" : "server") + "IdeaFormat_$project.name", Exec) { - def inspectionPath - def params = ["-r", "-mask", "*.java,*.kt,*.xml"] - for (String source : sources) { - params.add(source) - } - - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - inspectionPath = ['cmd', '/c', "\"${ideaPath}\\bin\\format.bat\" ${params.join(" ")}"] - } else { - inspectionPath = ["$ideaPath/bin/format.sh"] - } - commandLine inspectionPath - if (!Os.isFamily(Os.FAMILY_WINDOWS)) { - args = params - } - } -} - -ext.getStaticAnalysisTaskNames = { isAndroidProject, sources, buildVariant -> - def tasksNames = new ArrayList() - try { - tasksNames.add(getCpdTask(isAndroidProject, sources)) - tasksNames.addAll(getKotlinDetektTasks()) - if (isAndroidProject) { - tasksNames.add(getLintTask(buildVariant)) - } - } catch (Exception exception) { - println(exception.toString()) - } - return tasksNames -} - -ext.generateReport = { isAndroidProject -> - StringBuilder consoleReport = new StringBuilder() - consoleReport.append("STATIC ANALYSIS RESULTS:") - def count = 0 - - def previousCount = count - count = appendCpdErrors(count, new File("${project.buildDir}/reports/cpd.xml")) - if (count - previousCount > 0) { - consoleReport.append("\nCPD: FAILED (" + (count - previousCount) + " errors)") - } else { - consoleReport.append("\nCPD: PASSED") - } - - previousCount = count - subprojects.forEach { subproject -> - def reportFile = new File("${rootProject.buildDir}/reports/kotlin-detekt-${subproject.name}.xml") - if (reportFile.exists()) { - count = appendKotlinErrors(count, reportFile).toInteger() - } - } - if (count - previousCount > 0) { - consoleReport.append("\nKotlin-detekt: FAILED (" + (count - previousCount) + " errors)") - } else { - consoleReport.append("\nKotlin-detekt: PASSED") - } - - if (isAndroidProject) { - previousCount = count - count = appendLintErrors(count, new File("${rootProject.buildDir}/reports/lint_report.xml")) - if (count - previousCount > 0) { - consoleReport.append("\nLint: FAILED (" + (count - previousCount) + " errors)") - } else { - consoleReport.append("\nLint: PASSED") - } - } - - if (count > 0) { - consoleReport.append("\nOverall: FAILED (" + count + " errors)") - throw new Exception(consoleReport.toString()) - } else { - consoleReport.append("\nOverall: PASSED") - println(consoleReport.toString()) - } -} - -appendError = { number, analyzer, file, line, errorId, errorLink, description -> - println("$number. $analyzer : $description ($errorId)\n\tat $file: $line") -} - -appendKotlinErrors = { 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++ - - appendError(count, "Detekt", fileNode.attribute("name"), errorNode.attribute("line"), errorNode.attribute("source"), "", errorNode.attribute("message")) - } - } - return count -} - -appendCpdErrors = { count, cpdFile -> - def rootNode = new XmlParser().parse(cpdFile) - for (def duplicationNode : rootNode.children()) { - if (!duplicationNode.name().equals("duplication")) { - continue - } - count++ - - 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") - duplicationPoints += "\n " + file + ":" + line - duplicationIndex++ - } - } - println("$count CPD: code duplication $duplicationPoints") - } - return count -} - -appendLintErrors = { 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(count, "Lint", locationNode.attribute("file"), locationNode.attribute("line"), - issueNode.attribute("id"), issueNode.attribute("explanation"), issueNode.attribute("message")) - } - } - return count -} - -getCpdTask = { isAndroidProject, sources -> - def taskName = (isAndroidProject ? "android" : "server") + "cpd_${rootProject.name}" - def task = tasks.findByName(taskName) - if (task == null) { - task = tasks.create(taskName, tasks.findByName('cpdCheck').getClass().getSuperclass()) { - minimumTokenCount = 60 - source = files(sources) - ignoreFailures = true - reports { - xml { - enabled = true - destination = file("${rootProject.buildDir}/reports/cpd.xml") - } - } - } - } - return task.path -} - -getLintTask = { buildVariant -> - def appProject = subprojects.find { it.plugins.hasPlugin("com.android.application") } - def lintTaskPath - if (buildVariant != null) { - lintTaskPath = ":${appProject.name}:lint${buildVariant.name.capitalize()}" - } else { - def lintDebugTasks = appProject.tasks.matching { it.getName().contains("lint") && it.getName().contains("Debug") } - lintTaskPath = lintDebugTasks.first().path - } - if (lintTaskPath == null) { - throw IllegalStateException("Unable to find lint debug task for build variant: ${buildVariant}") - } - return lintTaskPath -} - -getKotlinDetektTasks = { - subprojects - .findResults { it.tasks.findByName("detekt")?.path } - .findAll { !it.contains(":libs") } -} - -task optimizePng { - doFirst { - def jarArgs = new ArrayList() - 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)) - } - for (def file : fileTree(dir: "${rootDir}", include: '**/src/**/res/mipmap**/*.png')) { - jarArgs.add(file.absolutePath.substring(relatedPathIndex)) - } - javaexec { main = "-jar"; args = jarArgs; workingDir = file("${rootDir}") } - } -} - -dependencies { - pngtastic 'com.github.depsypher:pngtastic:1.2' -} diff --git a/gradle/plugins/.gitignore b/gradle/plugins/.gitignore new file mode 100644 index 0000000..d7e7478 --- /dev/null +++ b/gradle/plugins/.gitignore @@ -0,0 +1,19 @@ +# Generated files +bin/ +gen/ + +# Gradle files +.gradle/ +build/ +/*/build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Log Files +*.log +.gradle +.idea +.DS_Store +/captures +*.iml diff --git a/gradle/plugins/build.gradle.kts b/gradle/plugins/build.gradle.kts new file mode 100644 index 0000000..3611bcb --- /dev/null +++ b/gradle/plugins/build.gradle.kts @@ -0,0 +1,52 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + `java-gradle-plugin` + `kotlin-dsl` +} + +// The kotlin-dsl plugin requires a repository to be declared +repositories { + jcenter() + google() +} + +dependencies { + // android gradle plugin, required by custom plugin + implementation("com.android.tools.build:gradle:4.0.1") + + implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.10.0") + implementation("de.aaschmid:gradle-cpd-plugin:3.1") + + // kotlin plugin, required by custom plugin + implementation(kotlin("gradle-plugin", embeddedKotlinVersion)) + + gradleKotlinDsl() + implementation(kotlin("stdlib-jdk8")) +} + +val compileKotlin: KotlinCompile by tasks +compileKotlin.kotlinOptions { + jvmTarget = "1.8" +} + +gradlePlugin { + plugins { + create("api-generator-android") { + id = "api-generator-android" + implementationClass = "apigen.ApiGeneratorAndroidPlugin" + } + create("api-generator-backend") { + id = "api-generator-backend" + implementationClass = "apigen.ApiGeneratorBackendPlugin" + } + create("static-analysis-android") { + id = "static-analysis-android" + implementationClass = "static_analysis.plugins.StaticAnalysisAndroidPlugin" + } + create("static-analysis-backend") { + id = "static-analysis-backend" + implementationClass = "static_analysis.plugins.StaticAnalysisBackendPlugin" + } + } +} diff --git a/gradle/plugins/settings.gradle.kts b/gradle/plugins/settings.gradle.kts new file mode 100644 index 0000000..e69de29 diff --git a/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt b/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt new file mode 100644 index 0000000..fa417b0 --- /dev/null +++ b/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt @@ -0,0 +1,37 @@ +package apigen + +import com.android.build.gradle.LibraryExtension +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +class ApiGeneratorAndroidPlugin : ApiGeneratorPlugin() { + + override fun apply(target: Project) { + super.apply(target) + + with(target) { + val extension = getExtension() + val outputDir = getDirectoryForGeneration() + + extension.outputDirPath = outputDir.path + extension.recreateOutputDir = true + + afterEvaluate { + extensions.getByType().apply { + sourceSets.getByName("main") + .java + .srcDir(outputDir) + } + tasks + .filterIsInstance(KotlinCompile::class.java) + .forEach { + it.source(outputDir) + } + } + } + } + + private fun Project.getDirectoryForGeneration() = file("$buildDir/generated/api") + +} diff --git a/gradle/plugins/src/main/java/apigen/ApiGeneratorBackendPlugin.kt b/gradle/plugins/src/main/java/apigen/ApiGeneratorBackendPlugin.kt new file mode 100644 index 0000000..b68eccf --- /dev/null +++ b/gradle/plugins/src/main/java/apigen/ApiGeneratorBackendPlugin.kt @@ -0,0 +1,19 @@ +package apigen + +import org.gradle.api.Project + +class ApiGeneratorBackendPlugin : ApiGeneratorPlugin() { + + override fun apply(target: Project) { + super.apply(target) + + with(target) { + val extension = getExtension() + + extension.outputDirPath = file("src/main/kotlin").path + extension.recreateOutputDir = false + extension.outputLanguage = OutputLanguage.KotlinServer + + } + } +} diff --git a/gradle/plugins/src/main/java/apigen/ApiGeneratorExtension.kt b/gradle/plugins/src/main/java/apigen/ApiGeneratorExtension.kt new file mode 100644 index 0000000..76e0ed9 --- /dev/null +++ b/gradle/plugins/src/main/java/apigen/ApiGeneratorExtension.kt @@ -0,0 +1,22 @@ +package apigen + +open class ApiGeneratorExtension( + var pathToApiSchemes: String? = null, + var outputPackageName: String = "", + var outputDirPath: String = "", + var recreateOutputDir: Boolean = false, + var outputLanguage: OutputLanguage? = null +) + +sealed class OutputLanguage(val argName: String, val methodOutputType: MethodOutputType? = null) { + object KotlinServer : OutputLanguage("KOTLIN_SERVER") + class KotlinAndroid(methodOutputType: MethodOutputType = MethodOutputType.Rx) : OutputLanguage("KOTLIN", methodOutputType) + object Java : OutputLanguage("JAVA") + object Swift : OutputLanguage("SWIFT") +} + +sealed class MethodOutputType(val argName: String) { + object Rx : MethodOutputType("REACTIVE") + object RetrofitCall : MethodOutputType("CALL") + object Coroutine : MethodOutputType("COROUTINE") +} diff --git a/gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt b/gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt new file mode 100644 index 0000000..ff272ce --- /dev/null +++ b/gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt @@ -0,0 +1,76 @@ +package apigen + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.repositories + +abstract class ApiGeneratorPlugin : Plugin { + + companion object { + const val API_GENERATOR_CONFIG = "apiGenerator" + const val API_GENERATOR_EXT_NAME = "apiGenerator" + const val API_GENERATOR_VERSION = "1.4.0-beta4" + } + + override fun apply(target: Project) { + with(target) { + repositories { + maven { + url = uri("https://dl.bintray.com/touchin/touchin-tools") + metadataSources { + artifact() + } + } + } + + configurations.create(API_GENERATOR_CONFIG) + + dependencies { + add(API_GENERATOR_CONFIG, "ru.touchin:api-generator:$API_GENERATOR_VERSION") + } + + extensions.create(API_GENERATOR_EXT_NAME) + + val apiGenTask = createApiGeneratorTask() + + gradle.projectsEvaluated { + tasks.getByName("preBuild").dependsOn(apiGenTask) + } + } + } + + protected fun Project.getExtension(): ApiGeneratorExtension = extensions.getByName(API_GENERATOR_EXT_NAME) as ApiGeneratorExtension + + private fun Project.createApiGeneratorTask(): Task = tasks.create(API_GENERATOR_CONFIG).doLast { + + val extension = getExtension() + + val pathToApiSchemes = extension.pathToApiSchemes ?: throw IllegalStateException("Configure path to api schemes for api generator plugin") + val outputLanguage = extension.outputLanguage ?: throw IllegalStateException("Configure output language code for api generator plugin") + + javaexec { + main = "-jar" + workingDir = rootDir + args = listOfNotNull( + configurations.getByName("apiGenerator").asPath, + "generate-client-code", + "--output-language", + outputLanguage.argName, + "--specification-path", + pathToApiSchemes, + "--kotlin-methods-generation-mode".takeIf { outputLanguage.methodOutputType != null }, + outputLanguage.methodOutputType?.argName, + "--output-path", + extension.outputDirPath, + "--package-name", + extension.outputPackageName, + "--recreate_output_dirs", + extension.recreateOutputDir.toString() + ) + } + } + +} diff --git a/gradle/plugins/src/main/java/static_analysis/errors/AndroidLintError.kt b/gradle/plugins/src/main/java/static_analysis/errors/AndroidLintError.kt new file mode 100644 index 0000000..aee4a44 --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/errors/AndroidLintError.kt @@ -0,0 +1,12 @@ +package static_analysis.errors + +class AndroidLintError( + private val filePath: String, + private val fileLine: String, + private val errorId: String, + private val description: String +) : StaticAnalysisError { + + override fun print(count: Int): String = "\n$count. Android Lint. $description ($errorId)\n\tat [$filePath:$fileLine]" + +} diff --git a/gradle/plugins/src/main/java/static_analysis/errors/CpdError.kt b/gradle/plugins/src/main/java/static_analysis/errors/CpdError.kt new file mode 100644 index 0000000..cca1c8a --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/errors/CpdError.kt @@ -0,0 +1,12 @@ +package static_analysis.errors + +class CpdError( + private val duplications: List>, + private val codeFragment: String +) : StaticAnalysisError { + + override fun print(count: Int): String = "\n$count. CPD. Code duplication in files: " + + duplications.joinToString(separator = "") { (file, line) -> "\n\t[$file:$line]" } + + "\n\n Duplicated code:\n\n$codeFragment\n" + +} diff --git a/gradle/plugins/src/main/java/static_analysis/errors/DetektError.kt b/gradle/plugins/src/main/java/static_analysis/errors/DetektError.kt new file mode 100644 index 0000000..3aa9c09 --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/errors/DetektError.kt @@ -0,0 +1,12 @@ +package static_analysis.errors + +class DetektError( + private val filePath: String, + private val fileLine: String, + private val errorId: String, + private val description: String +) : StaticAnalysisError { + + override fun print(count: Int): String = "\n$count. Detekt. $description ($errorId)\n\tat [$filePath:$fileLine]" + +} diff --git a/gradle/plugins/src/main/java/static_analysis/errors/StaticAnalysisError.kt b/gradle/plugins/src/main/java/static_analysis/errors/StaticAnalysisError.kt new file mode 100644 index 0000000..f932aca --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/errors/StaticAnalysisError.kt @@ -0,0 +1,5 @@ +package static_analysis.errors + +interface StaticAnalysisError { + fun print(count: Int): String +} diff --git a/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt b/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt new file mode 100644 index 0000000..f299d22 --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt @@ -0,0 +1,65 @@ +package static_analysis.linters + +import com.android.build.gradle.AppExtension +import com.android.build.gradle.AppPlugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.findByType +import static_analysis.errors.AndroidLintError +import static_analysis.errors.StaticAnalysisError +import static_analysis.plugins.StaticAnalysisExtension +import static_analysis.utils.typedChildren +import static_analysis.utils.xmlParser + +class AndroidLinter : Linter { + + override val name: String = "Android lint" + + override fun getErrors(project: Project): List = xmlParser(project.getLintReportFile()) + .typedChildren() + .filter { it.name() == "issue" && (it.attribute("severity") as String) == "Error" } + .map { errorNode -> + errorNode + .typedChildren() + .filter { it.name() == "location" } + .map { locationNode -> + AndroidLintError( + filePath = locationNode.attribute("file") as String, + fileLine = locationNode.attribute("line") as String, + errorId = errorNode.attribute("id") as String, + description = errorNode.attribute("message") as String + ) + } + } + .flatten() + + override fun setupForProject(project: Project, extension: StaticAnalysisExtension) { + project.gradle.projectsEvaluated { + project.subprojects + .mapNotNull { it.extensions.findByType() } + .first() + .lintOptions.apply { + isAbortOnError = false + isCheckAllWarnings = true + isWarningsAsErrors = false + xmlReport = true + htmlReport = false + isCheckDependencies = true + disable("MissingConstraints", "VectorRaster") + xmlOutput = project.getLintReportFile() + lintConfig = project.file("${extension.buildScriptDir}/static_analysis_configs/lint.xml") + } + } + } + + override fun getTaskNames(project: Project, buildType: String?): List = project + .subprojects + .filter { it.plugins.hasPlugin(AppPlugin::class.java) } + .mapNotNull { subproject: Project -> + subproject.tasks.find { task -> + task.name.contains(buildType!!, ignoreCase = true) && task.name.contains("lint") + }?.path + } + + private fun Project.getLintReportFile() = file("${rootProject.buildDir}/reports/lint-report.xml") + +} diff --git a/gradle/plugins/src/main/java/static_analysis/linters/CpdLinter.kt b/gradle/plugins/src/main/java/static_analysis/linters/CpdLinter.kt new file mode 100644 index 0000000..ca3ff7e --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/linters/CpdLinter.kt @@ -0,0 +1,57 @@ +package static_analysis.linters + +import de.aaschmid.gradle.plugins.cpd.Cpd +import de.aaschmid.gradle.plugins.cpd.CpdExtension +import org.gradle.api.Project +import org.gradle.kotlin.dsl.findByType +import org.gradle.kotlin.dsl.withType +import static_analysis.errors.CpdError +import static_analysis.errors.StaticAnalysisError +import static_analysis.plugins.StaticAnalysisExtension +import static_analysis.utils.getSources +import static_analysis.utils.typedChildren +import static_analysis.utils.xmlParser + +class CpdLinter : Linter { + + override val name: String = "CPD" + + override fun getErrors(project: Project): List = xmlParser(project.getCpdReportFile()) + .typedChildren() + .filter { it.name() == "duplication" } + .map { duplicationNode -> + + val children = duplicationNode + .typedChildren() + + CpdError( + duplications = children + .filter { it.name() == "file" } + .map { fileNode -> fileNode.attribute("path") as String to fileNode.attribute("line") as String }, + codeFragment = children.findLast { it.name() == "codefragment" }!!.text() + ) + + } + + override fun setupForProject(project: Project, extension: StaticAnalysisExtension) { + project.extensions.findByType()!!.apply { + isSkipLexicalErrors = true + language = "kotlin" + minimumTokenCount = 60 + } + project.tasks.withType { + reports.xml.destination = project.getCpdReportFile() + ignoreFailures = true + source = project.getSources(extension.excludes) + } + } + + override fun getTaskNames(project: Project, buildType: String?): List = project + .rootProject + .tasks + .withType() + .map { it.path } + + private fun Project.getCpdReportFile() = file("${rootProject.buildDir}/reports/cpd.xml") + +} diff --git a/gradle/plugins/src/main/java/static_analysis/linters/DetektLinter.kt b/gradle/plugins/src/main/java/static_analysis/linters/DetektLinter.kt new file mode 100644 index 0000000..0aafb22 --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/linters/DetektLinter.kt @@ -0,0 +1,62 @@ +package static_analysis.linters + +import io.gitlab.arturbosch.detekt.Detekt +import org.gradle.api.Project +import static_analysis.errors.DetektError +import static_analysis.errors.StaticAnalysisError +import static_analysis.plugins.StaticAnalysisExtension +import static_analysis.utils.getSources +import static_analysis.utils.typedChildren +import static_analysis.utils.xmlParser + +class DetektLinter : Linter { + + override val name: String = "Detekt" + + override fun getErrors(project: Project): List = xmlParser(project.getDetektReportFile()) + .typedChildren() + .filter { fileNode -> fileNode.name() == "file" } + .map { fileNode -> + fileNode + .typedChildren() + .filter { it.name() == "error" } + .map { errorNode -> + DetektError( + filePath = fileNode.attribute("name") as String, + fileLine = errorNode.attribute("line") as String, + errorId = errorNode.attribute("source") as String, + description = errorNode.attribute("message") as String + ) + } + } + .flatten() + + override fun setupForProject(project: Project, extension: StaticAnalysisExtension) { + project + .tasks + .withType(Detekt::class.java) { + exclude("**/test/**") + exclude("resources/") + exclude("build/") + exclude("tmp/") + jvmTarget = "1.8" + + config.setFrom(project.files("${extension.buildScriptDir!!}/static_analysis_configs/detekt-config.yml")) + reports { + txt.enabled = false + html.enabled = false + xml { + enabled = true + destination = project.getDetektReportFile() + } + } + + source = project.getSources(extension.excludes) + } + } + + override fun getTaskNames(project: Project, buildType: String?): List = listOf(":detekt") + + private fun Project.getDetektReportFile() = file("${rootProject.buildDir}/reports/detekt.xml") + +} diff --git a/gradle/plugins/src/main/java/static_analysis/linters/Linter.kt b/gradle/plugins/src/main/java/static_analysis/linters/Linter.kt new file mode 100644 index 0000000..65421a1 --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/linters/Linter.kt @@ -0,0 +1,12 @@ +package static_analysis.linters + +import org.gradle.api.Project +import static_analysis.errors.StaticAnalysisError +import static_analysis.plugins.StaticAnalysisExtension + +interface Linter { + val name: String + fun getErrors(project: Project): List + fun setupForProject(project: Project, extension: StaticAnalysisExtension) + fun getTaskNames(project: Project, buildType: String? = null): List +} diff --git a/gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisAndroidPlugin.kt b/gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisAndroidPlugin.kt new file mode 100644 index 0000000..c433e81 --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisAndroidPlugin.kt @@ -0,0 +1,43 @@ +package static_analysis.plugins + +import com.android.build.gradle.AppExtension +import org.gradle.api.Project +import org.gradle.kotlin.dsl.getByType +import static_analysis.linters.AndroidLinter +import static_analysis.linters.CpdLinter +import static_analysis.linters.DetektLinter +import static_analysis.linters.Linter + +class StaticAnalysisAndroidPlugin : StaticAnalysisPlugin() { + + override fun createStaticAnalysisTasks(project: Project, linters: List) { + project.subprojects { + if (plugins.hasPlugin("com.android.application")) { + + extensions.getByType().apply { + applicationVariants.forEach { variant -> + project.tasks.register("staticAnalysis${variant.name.capitalize()}") { + setupStaticAnalysisTask(linters, variant.name) + } + } + + project.tasks.register("staticAnalysis") { + setupStaticAnalysisTask( + linters = linters, + buildVariant = applicationVariants.first { it.name.contains("Debug") }.name + ) + } + } + + + } + } + } + + override fun createLinters(): List = listOf( + DetektLinter(), + CpdLinter(), + AndroidLinter() + ) + +} diff --git a/gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisBackendPlugin.kt b/gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisBackendPlugin.kt new file mode 100644 index 0000000..fa35f1d --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisBackendPlugin.kt @@ -0,0 +1,21 @@ +package static_analysis.plugins + +import org.gradle.api.Project +import static_analysis.linters.CpdLinter +import static_analysis.linters.DetektLinter +import static_analysis.linters.Linter + +class StaticAnalysisBackendPlugin : StaticAnalysisPlugin() { + + override fun createStaticAnalysisTasks(project: Project, linters: List) { + project.tasks.register("staticAnalysis") { + setupStaticAnalysisTask(linters) + } + } + + override fun createLinters(): List = listOf( + CpdLinter(), + DetektLinter() + ) + +} diff --git a/gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisExtension.kt b/gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisExtension.kt new file mode 100644 index 0000000..dfa698d --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisExtension.kt @@ -0,0 +1,6 @@ +package static_analysis.plugins + +open class StaticAnalysisExtension( + var excludes: String = "", + var buildScriptDir: String? = null +) diff --git a/gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisPlugin.kt b/gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisPlugin.kt new file mode 100644 index 0000000..38ded00 --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/plugins/StaticAnalysisPlugin.kt @@ -0,0 +1,47 @@ +package static_analysis.plugins + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.getByType +import static_analysis.linters.Linter +import static_analysis.utils.ReportGenerator + +abstract class StaticAnalysisPlugin : Plugin { + + companion object { + const val DETEKT_ID = "io.gitlab.arturbosch.detekt" + const val CPD_ID = "de.aaschmid.cpd" + const val STATIC_ANALYSIS_EXT_NAME = "staticAnalysis" + } + + override fun apply(target: Project) { + + with(target) { + pluginManager.apply(CPD_ID) + pluginManager.apply(DETEKT_ID) + + extensions.create(STATIC_ANALYSIS_EXT_NAME) + + val linters = createLinters() + + afterEvaluate { + linters.forEach { it.setupForProject(target, extensions.getByType()) } + } + + gradle.projectsEvaluated { + createStaticAnalysisTasks(target, linters) + } + } + } + + fun Task.setupStaticAnalysisTask(linters: List, buildVariant: String? = null) { + doFirst { ReportGenerator.generate(linters, project) } + dependsOn(*(linters.map { it.getTaskNames(project, buildVariant) }.flatten().toTypedArray())) + } + + abstract fun createLinters(): List + abstract fun createStaticAnalysisTasks(project: Project, linters: List) + +} diff --git a/gradle/plugins/src/main/java/static_analysis/utils/Extensions.kt b/gradle/plugins/src/main/java/static_analysis/utils/Extensions.kt new file mode 100644 index 0000000..c53ce16 --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/utils/Extensions.kt @@ -0,0 +1,33 @@ +package static_analysis.utils + +import groovy.util.Node +import groovy.util.XmlParser +import org.gradle.api.Project +import org.gradle.api.file.FileTree +import java.io.File + +fun Node.typedChildren() = children() as List + +fun xmlParser(file: File) = XmlParser().parse(file) + +fun Project.getSources(excludes: String): FileTree = files( + project + .rootProject + .subprojects + .filter { subproject -> subproject.subprojects.isEmpty() && !excludes.contains(subproject.path) } + .map { subproject -> subproject.file("${subproject.projectDir.path}/src/main") } + .filter { it.exists() && it.isDirectory } + .flatMap { srcDir -> + srcDir + .listFiles() + .orEmpty() + .flatMap { + listOf( + File(srcDir.path, "java"), + File(srcDir.path, "kotlin") + ) + } + } + .filter { it.exists() && it.isDirectory } + .map { it.path } +).asFileTree diff --git a/gradle/plugins/src/main/java/static_analysis/utils/ReportGenerator.kt b/gradle/plugins/src/main/java/static_analysis/utils/ReportGenerator.kt new file mode 100644 index 0000000..caf543e --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/utils/ReportGenerator.kt @@ -0,0 +1,52 @@ +package static_analysis.utils + +import org.gradle.api.Project +import static_analysis.errors.StaticAnalysisError +import static_analysis.linters.Linter + +object ReportGenerator { + + fun generate(linters: List, project: Project) { + + val groupedErrors = linters + .map { linter -> linter to linter.getErrors(project) } + + val lintersResults = groupedErrors + .map { it.first.name to it.second.size } + + val allErrors = groupedErrors + .map { it.second } + .flatten() + + val consoleReport = StringBuilder("\nSTATIC ANALYSIS ERRORS:").apply { + appendAllErrors(allErrors) + append("\nREPORT:\n") + appendReportsSummary(lintersResults) + appendOverallSummary(allErrors) + } + + if (allErrors.isEmpty()) { + println(consoleReport) + } else { + throw Exception(consoleReport.toString()) + } + + } + + private fun StringBuilder.appendAllErrors(errors: List) = errors + .mapIndexed { index, staticAnalysisError -> staticAnalysisError.print(index + 1) } + .forEach { error -> append(error) } + + private fun StringBuilder.appendReportsSummary(lintersResults: List>) = lintersResults + .forEach { this.appendSummary(it.first, it.second) } + + private fun StringBuilder.appendOverallSummary(errors: List) = appendSummary("Overall", errors.size) + + private fun StringBuilder.appendSummary(header: String, quantityOfErrors: Int) { + assert(quantityOfErrors < 0) + + append("\n$header: ") + append(if (quantityOfErrors == 0) "PASSED" else "FAILED ($quantityOfErrors errors)") + } + +} diff --git a/gradle/applicationFileNaming.gradle b/gradle/scripts/applicationFileNaming.gradle similarity index 100% rename from gradle/applicationFileNaming.gradle rename to gradle/scripts/applicationFileNaming.gradle diff --git a/gradle/stringGenerator.gradle b/gradle/scripts/stringGenerator.gradle similarity index 100% rename from gradle/stringGenerator.gradle rename to gradle/scripts/stringGenerator.gradle diff --git a/gradle/staticAnalysis.gradle b/gradle/staticAnalysis.gradle deleted file mode 100644 index b952ec9..0000000 --- a/gradle/staticAnalysis.gradle +++ /dev/null @@ -1,166 +0,0 @@ -buildscript { - repositories { - maven { url "https://plugins.gradle.org/m2" } - } - dependencies { - classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.5.1" - } -} - -def getServerProjectSources -def getAndroidProjectSources - -apply from: "$buildScriptsDir/gradle/commonStaticAnalysis.gradle" - -gradle.projectsEvaluated { - - tasks.withType(JavaCompile) { - options.compilerArgs << - "-Xlint:cast" << - "-Xlint:divzero" << - "-Xlint:empty" << - "-Xlint:deprecation" << - "-Xlint:finally" << - "-Xlint:overrides" << - "-Xlint:path" << - "-Werror" - } - - def excludes = rootProject.extensions.findByName("staticAnalysisExcludes") - - def androidSources = getAndroidProjectSources(excludes) - def androidStaticAnalysisTasks = getStaticAnalysisTaskNames(true, androidSources, null) - def androidIdeaFormatTask = getIdeaFormatTask(true, androidSources) - - task staticAnalysisWithFormatting { - androidStaticAnalysisTasks.each { task -> - tasks.findByName(task)?.mustRunAfter(androidIdeaFormatTask) - } - dependsOn androidIdeaFormatTask - dependsOn androidStaticAnalysisTasks - doFirst { - generateReport(true) - } - } - - task staticAnalysis { - dependsOn androidStaticAnalysisTasks - doFirst { - generateReport(true) - } - } - - def serverStaticAnalysisTasks = getStaticAnalysisTaskNames(false, getServerProjectSources(excludes), null) - def serverIdeaFormatTask = getIdeaFormatTask(false, getServerProjectSources(excludes)) - - task serverStaticAnalysisWithFormatting { - serverStaticAnalysisTasks.each { task -> - tasks.findByName(task)?.mustRunAfter(serverIdeaFormatTask) - } - dependsOn serverIdeaFormatTask - dependsOn serverStaticAnalysisTasks - doFirst { - generateReport(false) - } - } - - task serverStaticAnalysis { - dependsOn serverStaticAnalysisTasks - doFirst { - generateReport(false) - } - } - - subprojects { subproject -> - if (subproject.plugins.hasPlugin("com.android.application")) { - subproject.android { - lintOptions.abortOnError = false - lintOptions.checkAllWarnings = true - lintOptions.warningsAsErrors = false - lintOptions.xmlReport = true - lintOptions.xmlOutput = file "$rootProject.buildDir/reports/lint_report.xml" - lintOptions.htmlReport = false - lintOptions.lintConfig = file "$buildScriptsDir/lint/lint.xml" - lintOptions.checkDependencies true - lintOptions.disable 'MissingConstraints', 'VectorRaster' - - applicationVariants.all { variant -> - task("staticAnalysis${variant.name.capitalize()}") { - dependsOn getStaticAnalysisTaskNames(true, androidSources, variant) - doFirst { generateReport(true) } - } - } - } - } - - def regex = ~':detekt$' - tasks.forEach { task -> - if (!task.name.contains(":libs") && task.path =~ regex) { - task.exclude '**/test/**' - task.exclude 'resources/' - task.exclude 'build/' - task.exclude 'tmp/' - - task.jvmTarget = "1.8" - } - } - - detekt { - config = files("$buildScriptsDir/kotlin/detekt-config.yml") - - reports { - txt.enabled = false - html.enabled = false - xml { - enabled = true - destination = file("${rootProject.buildDir}/reports/kotlin-detekt-${subproject.name}.xml") - } - } - } - } -} - -getServerProjectSources = { excludes -> - def sources = new ArrayList() - def sourcesDirectory = new File(project.projectDir.path, 'src') - - for (def sourceFlavorDirectory : sourcesDirectory.listFiles()) { - def javaSourceDirectory = new File(sourceFlavorDirectory.path, 'java') - def kotlinSourceDirectory = new File(sourceFlavorDirectory.path, 'kotlin') - - if (javaSourceDirectory.exists() && javaSourceDirectory.isDirectory()) { - sources.add(javaSourceDirectory.absolutePath) - } - if (kotlinSourceDirectory.exists() && kotlinSourceDirectory.isDirectory()) { - sources.add(kotlinSourceDirectory.absolutePath) - } - } - return sources -} - -getAndroidProjectSources = { excludes -> - def sources = new ArrayList() - 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 javaSourceDirectory = new File(sourceFlavorDirectory.path, 'java') - def kotlinSourceDirectory = new File(sourceFlavorDirectory.path, 'kotlin') - - if (javaSourceDirectory.exists() && javaSourceDirectory.isDirectory()) { - sources.add(javaSourceDirectory.absolutePath) - } - if (kotlinSourceDirectory.exists() && kotlinSourceDirectory.isDirectory()) { - sources.add(kotlinSourceDirectory.absolutePath) - } - } - } - return sources -} diff --git a/lint/lint.xml b/lint/lint.xml deleted file mode 100644 index 57a80e9..0000000 --- a/lint/lint.xml +++ /dev/null @@ -1,272 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pmd/rulesets/java/android.xml b/pmd/rulesets/java/android.xml deleted file mode 100644 index debe6f4..0000000 --- a/pmd/rulesets/java/android.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - - Every Java Rule in PMD - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/export_src.sh b/scripts/export_src.sh similarity index 100% rename from export_src.sh rename to scripts/export_src.sh diff --git a/kotlin/detekt-config.yml b/static_analysis_configs/detekt-config.yml similarity index 99% rename from kotlin/detekt-config.yml rename to static_analysis_configs/detekt-config.yml index 3afb6fa..5ea4cce 100644 --- a/kotlin/detekt-config.yml +++ b/static_analysis_configs/detekt-config.yml @@ -23,7 +23,7 @@ formatting: active: true console-reports: - active: true + active: false exclude: # - 'ProjectStatisticsReport' # - 'ComplexityReport' diff --git a/static_analysis_configs/lint.xml b/static_analysis_configs/lint.xml new file mode 100644 index 0000000..98227d4 --- /dev/null +++ b/static_analysis_configs/lint.xml @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 0f53df4bb45903a2d748bb0d087a99fec3bcfd90 Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Wed, 19 Aug 2020 17:56:02 +0300 Subject: [PATCH 06/13] update api gen version --- gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt b/gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt index ff272ce..e0fc6ec 100644 --- a/gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt +++ b/gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt @@ -12,7 +12,7 @@ abstract class ApiGeneratorPlugin : Plugin { companion object { const val API_GENERATOR_CONFIG = "apiGenerator" const val API_GENERATOR_EXT_NAME = "apiGenerator" - const val API_GENERATOR_VERSION = "1.4.0-beta4" + const val API_GENERATOR_VERSION = "1.4.0-beta5" } override fun apply(target: Project) { From 7b54155ae1bd769dec94bd79edd43ead4dc2cfc0 Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Thu, 20 Aug 2020 13:33:57 +0300 Subject: [PATCH 07/13] fixed android api gen and string generator for old projects --- .../main/java/apigen/ApiGeneratorAndroidPlugin.kt | 10 ++++++++-- gradle/scripts/stringGenerator.gradle | 14 +++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt b/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt index fa417b0..0442f43 100644 --- a/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt +++ b/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt @@ -1,8 +1,9 @@ package apigen +import com.android.build.gradle.AppExtension import com.android.build.gradle.LibraryExtension import org.gradle.api.Project -import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.findByType import org.jetbrains.kotlin.gradle.tasks.KotlinCompile class ApiGeneratorAndroidPlugin : ApiGeneratorPlugin() { @@ -18,7 +19,12 @@ class ApiGeneratorAndroidPlugin : ApiGeneratorPlugin() { extension.recreateOutputDir = true afterEvaluate { - extensions.getByType().apply { + extensions.findByType()?.apply { + sourceSets.getByName("main") + .java + .srcDir(outputDir) + } + extensions.findByType()?.apply { sourceSets.getByName("main") .java .srcDir(outputDir) diff --git a/gradle/scripts/stringGenerator.gradle b/gradle/scripts/stringGenerator.gradle index 374ab12..9c47e90 100644 --- a/gradle/scripts/stringGenerator.gradle +++ b/gradle/scripts/stringGenerator.gradle @@ -2,11 +2,11 @@ import groovy.json.JsonSlurper import groovy.xml.MarkupBuilder task stringGenerator { - generate(android.languageMap, android.rootPath ?: "app") + generate(android.languageMap, project) println("Strings generated!") } -private def generate(Map sources, String rootPath) { +private def generate(Map sources, Project project) { if (sources == null || sources.isEmpty()) { throw new IOException("languageMap can't be null or empty") } @@ -31,7 +31,7 @@ private def generate(Map sources, String rootPath) { } } - def stringsFile = getFile(key, key == defaultLang, rootPath) + def stringsFile = getFile(key, key == defaultLang, project) stringsFile.write(sw.toString(), "UTF-8") } } @@ -69,15 +69,15 @@ private static Map getJsonsMap(Map sources) { } } -private static File getFile(String key, boolean defaultLang, String rootPath) { +private static File getFile(String key, boolean defaultLang, Project project) { if (defaultLang) { - return new File("${rootPath}/src/main/res/values/strings.xml") + return project.file("src/main/res/values/strings.xml") } else { - def directory = new File("${rootPath}/src/main/res/values-$key") + def directory = project.file("src/main/res/values-$key") if (!directory.exists()) { directory.mkdir() } - return new File("${rootPath}/src/main/res/values-$key/strings.xml") + return project.file("src/main/res/values-$key/strings.xml") } } From b3bff241398f0545fe1870b62371594c495e5825 Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Thu, 20 Aug 2020 15:22:41 +0300 Subject: [PATCH 08/13] fixed problem with source sets for java code --- .../src/main/java/apigen/ApiGeneratorAndroidPlugin.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt b/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt index 0442f43..d30c4f5 100644 --- a/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt +++ b/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt @@ -3,6 +3,7 @@ package apigen import com.android.build.gradle.AppExtension import com.android.build.gradle.LibraryExtension import org.gradle.api.Project +import org.gradle.api.tasks.compile.JavaCompile import org.gradle.kotlin.dsl.findByType import org.jetbrains.kotlin.gradle.tasks.KotlinCompile @@ -34,6 +35,12 @@ class ApiGeneratorAndroidPlugin : ApiGeneratorPlugin() { .forEach { it.source(outputDir) } + + tasks + .filterIsInstance() + .forEach { + it.source(outputDir) + } } } } From 3d73b2473f5d85af83f4a7392215a29d0f733221 Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Thu, 20 Aug 2020 15:24:04 +0300 Subject: [PATCH 09/13] little change of code's style --- .../plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt b/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt index d30c4f5..83295d3 100644 --- a/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt +++ b/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt @@ -31,7 +31,7 @@ class ApiGeneratorAndroidPlugin : ApiGeneratorPlugin() { .srcDir(outputDir) } tasks - .filterIsInstance(KotlinCompile::class.java) + .filterIsInstance() .forEach { it.source(outputDir) } From 21e21aca1d4ad49355cb51b549d1454cb97741a7 Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Thu, 20 Aug 2020 17:55:14 +0300 Subject: [PATCH 10/13] fix android lint bug with no file column errors --- .../src/main/java/static_analysis/errors/AndroidLintError.kt | 4 ++-- .../src/main/java/static_analysis/linters/AndroidLinter.kt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/plugins/src/main/java/static_analysis/errors/AndroidLintError.kt b/gradle/plugins/src/main/java/static_analysis/errors/AndroidLintError.kt index aee4a44..b7b850b 100644 --- a/gradle/plugins/src/main/java/static_analysis/errors/AndroidLintError.kt +++ b/gradle/plugins/src/main/java/static_analysis/errors/AndroidLintError.kt @@ -2,11 +2,11 @@ package static_analysis.errors class AndroidLintError( private val filePath: String, - private val fileLine: String, + private val fileLine: String?, private val errorId: String, private val description: String ) : StaticAnalysisError { - override fun print(count: Int): String = "\n$count. Android Lint. $description ($errorId)\n\tat [$filePath:$fileLine]" + override fun print(count: Int): String = "\n$count. Android Lint. $description ($errorId)\n\tat [$filePath${fileLine?.let { ":$it" }.orEmpty()}]" } diff --git a/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt b/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt index f299d22..3e19265 100644 --- a/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt +++ b/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt @@ -24,7 +24,7 @@ class AndroidLinter : Linter { .map { locationNode -> AndroidLintError( filePath = locationNode.attribute("file") as String, - fileLine = locationNode.attribute("line") as String, + fileLine = locationNode.attribute("line") as String?, errorId = errorNode.attribute("id") as String, description = errorNode.attribute("message") as String ) From a8e55fc0e856425fc81428197ab704694c90a4d7 Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Wed, 2 Sep 2020 17:48:46 +0300 Subject: [PATCH 11/13] fix proguard cut annotation which used in custom json adapter --- proguard/rules/moshi.pro | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 proguard/rules/moshi.pro diff --git a/proguard/rules/moshi.pro b/proguard/rules/moshi.pro new file mode 100644 index 0000000..fe81601 --- /dev/null +++ b/proguard/rules/moshi.pro @@ -0,0 +1,23 @@ +# JSR 305 annotations are for embedding nullability information. +-dontwarn javax.annotation.** + +-keepclasseswithmembers class * { + @com.squareup.moshi.* ; +} + +-keep @com.squareup.moshi.JsonQualifier interface * +-keep @com.squareup.moshi.JsonQualifier class * + +# Enum field names are used by the integrated EnumJsonAdapter. +# values() is synthesized by the Kotlin compiler and is used by EnumJsonAdapter indirectly +# Annotate enums with @JsonClass(generateAdapter = false) to use them with Moshi. +-keepclassmembers @com.squareup.moshi.JsonClass class * extends java.lang.Enum { + ; + **[] values(); +} + +-keep class kotlin.reflect.jvm.internal.impl.builtins.BuiltInsLoaderImpl + +-keepclassmembers class kotlin.Metadata { + public ; +} From 487291a54fd5fdb0d3b028d0b3e57adb28fe280b Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Tue, 8 Sep 2020 15:42:47 +0300 Subject: [PATCH 12/13] fix code review --- gradle/plugins/.gitignore | 1 + .../java/apigen/ApiGeneratorAndroidPlugin.kt | 8 ++----- .../java/apigen/ApiGeneratorBackendPlugin.kt | 10 ++++----- .../main/java/apigen/ApiGeneratorPlugin.kt | 4 ++-- .../errors/AndroidLintError.kt | 5 ++++- .../static_analysis/linters/AndroidLinter.kt | 22 +++++++++++-------- .../java/static_analysis/linters/CpdLinter.kt | 4 ++-- .../static_analysis/linters/DetektLinter.kt | 2 +- .../main/java/static_analysis/utils/Node.kt | 5 +++++ .../utils/{Extensions.kt => Project.kt} | 6 ----- .../static_analysis/utils/ReportGenerator.kt | 4 ++-- .../java/static_analysis/utils/XmlUtils.kt | 4 ++++ proguard/common.pro | 2 +- 13 files changed, 41 insertions(+), 36 deletions(-) create mode 100644 gradle/plugins/src/main/java/static_analysis/utils/Node.kt rename gradle/plugins/src/main/java/static_analysis/utils/{Extensions.kt => Project.kt} (87%) create mode 100644 gradle/plugins/src/main/java/static_analysis/utils/XmlUtils.kt diff --git a/gradle/plugins/.gitignore b/gradle/plugins/.gitignore index d7e7478..39d12d8 100644 --- a/gradle/plugins/.gitignore +++ b/gradle/plugins/.gitignore @@ -12,6 +12,7 @@ local.properties # Log Files *.log + .gradle .idea .DS_Store diff --git a/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt b/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt index 83295d3..ea06f40 100644 --- a/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt +++ b/gradle/plugins/src/main/java/apigen/ApiGeneratorAndroidPlugin.kt @@ -32,15 +32,11 @@ class ApiGeneratorAndroidPlugin : ApiGeneratorPlugin() { } tasks .filterIsInstance() - .forEach { - it.source(outputDir) - } + .forEach { it.source(outputDir) } tasks .filterIsInstance() - .forEach { - it.source(outputDir) - } + .forEach { it.source(outputDir) } } } } diff --git a/gradle/plugins/src/main/java/apigen/ApiGeneratorBackendPlugin.kt b/gradle/plugins/src/main/java/apigen/ApiGeneratorBackendPlugin.kt index b68eccf..b4a8723 100644 --- a/gradle/plugins/src/main/java/apigen/ApiGeneratorBackendPlugin.kt +++ b/gradle/plugins/src/main/java/apigen/ApiGeneratorBackendPlugin.kt @@ -7,13 +7,11 @@ class ApiGeneratorBackendPlugin : ApiGeneratorPlugin() { override fun apply(target: Project) { super.apply(target) - with(target) { - val extension = getExtension() + val extension = target.getExtension() - extension.outputDirPath = file("src/main/kotlin").path - extension.recreateOutputDir = false - extension.outputLanguage = OutputLanguage.KotlinServer + extension.outputDirPath = target.file("src/main/kotlin").path + extension.recreateOutputDir = false + extension.outputLanguage = OutputLanguage.KotlinServer - } } } diff --git a/gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt b/gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt index e0fc6ec..7e9b607 100644 --- a/gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt +++ b/gradle/plugins/src/main/java/apigen/ApiGeneratorPlugin.kt @@ -12,7 +12,7 @@ abstract class ApiGeneratorPlugin : Plugin { companion object { const val API_GENERATOR_CONFIG = "apiGenerator" const val API_GENERATOR_EXT_NAME = "apiGenerator" - const val API_GENERATOR_VERSION = "1.4.0-beta5" + const val API_GENERATOR_DEFAULT_VERSION = "1.4.0-beta5" } override fun apply(target: Project) { @@ -29,7 +29,7 @@ abstract class ApiGeneratorPlugin : Plugin { configurations.create(API_GENERATOR_CONFIG) dependencies { - add(API_GENERATOR_CONFIG, "ru.touchin:api-generator:$API_GENERATOR_VERSION") + add(API_GENERATOR_CONFIG, "ru.touchin:api-generator:$API_GENERATOR_DEFAULT_VERSION") } extensions.create(API_GENERATOR_EXT_NAME) diff --git a/gradle/plugins/src/main/java/static_analysis/errors/AndroidLintError.kt b/gradle/plugins/src/main/java/static_analysis/errors/AndroidLintError.kt index b7b850b..6b87d81 100644 --- a/gradle/plugins/src/main/java/static_analysis/errors/AndroidLintError.kt +++ b/gradle/plugins/src/main/java/static_analysis/errors/AndroidLintError.kt @@ -7,6 +7,9 @@ class AndroidLintError( private val description: String ) : StaticAnalysisError { - override fun print(count: Int): String = "\n$count. Android Lint. $description ($errorId)\n\tat [$filePath${fileLine?.let { ":$it" }.orEmpty()}]" + override fun print(count: Int): String = "\n$count. Android Lint. $description ($errorId)\n\tat [$filePath$fileLinePrefix]" + + private val fileLinePrefix: String + get() = fileLine?.let { ":$it" }.orEmpty() } diff --git a/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt b/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt index 3e19265..3853959 100644 --- a/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt +++ b/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt @@ -8,7 +8,7 @@ import static_analysis.errors.AndroidLintError import static_analysis.errors.StaticAnalysisError import static_analysis.plugins.StaticAnalysisExtension import static_analysis.utils.typedChildren -import static_analysis.utils.xmlParser +import xmlParser class AndroidLinter : Linter { @@ -51,14 +51,18 @@ class AndroidLinter : Linter { } } - override fun getTaskNames(project: Project, buildType: String?): List = project - .subprojects - .filter { it.plugins.hasPlugin(AppPlugin::class.java) } - .mapNotNull { subproject: Project -> - subproject.tasks.find { task -> - task.name.contains(buildType!!, ignoreCase = true) && task.name.contains("lint") - }?.path - } + override fun getTaskNames(project: Project, buildType: String?): List { + if (buildType == null) throw IllegalStateException("build type must not be null in android linter") + + return project + .subprojects + .filter { it.plugins.hasPlugin(AppPlugin::class.java) } + .mapNotNull { subproject: Project -> + subproject.tasks.find { task -> + task.name.contains(buildType, ignoreCase = true) && task.name.contains("lint") + }?.path + } + } private fun Project.getLintReportFile() = file("${rootProject.buildDir}/reports/lint-report.xml") diff --git a/gradle/plugins/src/main/java/static_analysis/linters/CpdLinter.kt b/gradle/plugins/src/main/java/static_analysis/linters/CpdLinter.kt index ca3ff7e..313d250 100644 --- a/gradle/plugins/src/main/java/static_analysis/linters/CpdLinter.kt +++ b/gradle/plugins/src/main/java/static_analysis/linters/CpdLinter.kt @@ -10,7 +10,7 @@ import static_analysis.errors.StaticAnalysisError import static_analysis.plugins.StaticAnalysisExtension import static_analysis.utils.getSources import static_analysis.utils.typedChildren -import static_analysis.utils.xmlParser +import xmlParser class CpdLinter : Linter { @@ -50,7 +50,7 @@ class CpdLinter : Linter { .rootProject .tasks .withType() - .map { it.path } + .map(Cpd::getPath) private fun Project.getCpdReportFile() = file("${rootProject.buildDir}/reports/cpd.xml") diff --git a/gradle/plugins/src/main/java/static_analysis/linters/DetektLinter.kt b/gradle/plugins/src/main/java/static_analysis/linters/DetektLinter.kt index 0aafb22..3905ce8 100644 --- a/gradle/plugins/src/main/java/static_analysis/linters/DetektLinter.kt +++ b/gradle/plugins/src/main/java/static_analysis/linters/DetektLinter.kt @@ -7,7 +7,7 @@ import static_analysis.errors.StaticAnalysisError import static_analysis.plugins.StaticAnalysisExtension import static_analysis.utils.getSources import static_analysis.utils.typedChildren -import static_analysis.utils.xmlParser +import xmlParser class DetektLinter : Linter { diff --git a/gradle/plugins/src/main/java/static_analysis/utils/Node.kt b/gradle/plugins/src/main/java/static_analysis/utils/Node.kt new file mode 100644 index 0000000..e8618e2 --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/utils/Node.kt @@ -0,0 +1,5 @@ +package static_analysis.utils + +import groovy.util.Node + +fun Node.typedChildren() = children() as List diff --git a/gradle/plugins/src/main/java/static_analysis/utils/Extensions.kt b/gradle/plugins/src/main/java/static_analysis/utils/Project.kt similarity index 87% rename from gradle/plugins/src/main/java/static_analysis/utils/Extensions.kt rename to gradle/plugins/src/main/java/static_analysis/utils/Project.kt index c53ce16..f1c46cf 100644 --- a/gradle/plugins/src/main/java/static_analysis/utils/Extensions.kt +++ b/gradle/plugins/src/main/java/static_analysis/utils/Project.kt @@ -1,15 +1,9 @@ package static_analysis.utils -import groovy.util.Node -import groovy.util.XmlParser import org.gradle.api.Project import org.gradle.api.file.FileTree import java.io.File -fun Node.typedChildren() = children() as List - -fun xmlParser(file: File) = XmlParser().parse(file) - fun Project.getSources(excludes: String): FileTree = files( project .rootProject diff --git a/gradle/plugins/src/main/java/static_analysis/utils/ReportGenerator.kt b/gradle/plugins/src/main/java/static_analysis/utils/ReportGenerator.kt index caf543e..b18f8f4 100644 --- a/gradle/plugins/src/main/java/static_analysis/utils/ReportGenerator.kt +++ b/gradle/plugins/src/main/java/static_analysis/utils/ReportGenerator.kt @@ -12,10 +12,10 @@ object ReportGenerator { .map { linter -> linter to linter.getErrors(project) } val lintersResults = groupedErrors - .map { it.first.name to it.second.size } + .map { (linter, linterErrors) -> linter.name to linterErrors.size } val allErrors = groupedErrors - .map { it.second } + .map(Pair>::second) .flatten() val consoleReport = StringBuilder("\nSTATIC ANALYSIS ERRORS:").apply { diff --git a/gradle/plugins/src/main/java/static_analysis/utils/XmlUtils.kt b/gradle/plugins/src/main/java/static_analysis/utils/XmlUtils.kt new file mode 100644 index 0000000..f335b29 --- /dev/null +++ b/gradle/plugins/src/main/java/static_analysis/utils/XmlUtils.kt @@ -0,0 +1,4 @@ +import groovy.util.XmlParser +import java.io.File + +fun xmlParser(file: File) = XmlParser().parse(file) diff --git a/proguard/common.pro b/proguard/common.pro index 52715c2..d7f2023 100644 --- a/proguard/common.pro +++ b/proguard/common.pro @@ -1,5 +1,4 @@ -include rules/components.pro - -include rules/okhttp.pro -include rules/retrofit.pro -include rules/logansquare.pro @@ -7,3 +6,4 @@ -include rules/glide.pro -include rules/kaspersky.pro -include rules/appsflyer.pro +-include rules/moshi.pro From adf2946881bf0490ad41418bf76e9c14cb925260 Mon Sep 17 00:00:00 2001 From: Maxim Bachinsky Date: Tue, 8 Sep 2020 19:04:43 +0300 Subject: [PATCH 13/13] fixed code review --- .../java/static_analysis/linters/AndroidLinter.kt | 13 ++++++++----- .../main/java/static_analysis/linters/CpdLinter.kt | 2 +- .../java/static_analysis/linters/DetektLinter.kt | 2 +- .../src/main/java/static_analysis/utils/XmlUtils.kt | 2 ++ 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt b/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt index 3853959..8550e04 100644 --- a/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt +++ b/gradle/plugins/src/main/java/static_analysis/linters/AndroidLinter.kt @@ -8,7 +8,7 @@ import static_analysis.errors.AndroidLintError import static_analysis.errors.StaticAnalysisError import static_analysis.plugins.StaticAnalysisExtension import static_analysis.utils.typedChildren -import xmlParser +import static_analysis.utils.xmlParser class AndroidLinter : Linter { @@ -52,15 +52,18 @@ class AndroidLinter : Linter { } override fun getTaskNames(project: Project, buildType: String?): List { - if (buildType == null) throw IllegalStateException("build type must not be null in android linter") + if (buildType == null) { + throw IllegalStateException("Build type must not be null in android linter") + } return project .subprojects .filter { it.plugins.hasPlugin(AppPlugin::class.java) } .mapNotNull { subproject: Project -> - subproject.tasks.find { task -> - task.name.contains(buildType, ignoreCase = true) && task.name.contains("lint") - }?.path + subproject + .tasks + .find { task -> task.name.contains(buildType, ignoreCase = true) && task.name.contains("lint") } + ?.path } } diff --git a/gradle/plugins/src/main/java/static_analysis/linters/CpdLinter.kt b/gradle/plugins/src/main/java/static_analysis/linters/CpdLinter.kt index 313d250..1e7395a 100644 --- a/gradle/plugins/src/main/java/static_analysis/linters/CpdLinter.kt +++ b/gradle/plugins/src/main/java/static_analysis/linters/CpdLinter.kt @@ -10,7 +10,7 @@ import static_analysis.errors.StaticAnalysisError import static_analysis.plugins.StaticAnalysisExtension import static_analysis.utils.getSources import static_analysis.utils.typedChildren -import xmlParser +import static_analysis.utils.xmlParser class CpdLinter : Linter { diff --git a/gradle/plugins/src/main/java/static_analysis/linters/DetektLinter.kt b/gradle/plugins/src/main/java/static_analysis/linters/DetektLinter.kt index 3905ce8..0aafb22 100644 --- a/gradle/plugins/src/main/java/static_analysis/linters/DetektLinter.kt +++ b/gradle/plugins/src/main/java/static_analysis/linters/DetektLinter.kt @@ -7,7 +7,7 @@ import static_analysis.errors.StaticAnalysisError import static_analysis.plugins.StaticAnalysisExtension import static_analysis.utils.getSources import static_analysis.utils.typedChildren -import xmlParser +import static_analysis.utils.xmlParser class DetektLinter : Linter { diff --git a/gradle/plugins/src/main/java/static_analysis/utils/XmlUtils.kt b/gradle/plugins/src/main/java/static_analysis/utils/XmlUtils.kt index f335b29..1754f4c 100644 --- a/gradle/plugins/src/main/java/static_analysis/utils/XmlUtils.kt +++ b/gradle/plugins/src/main/java/static_analysis/utils/XmlUtils.kt @@ -1,3 +1,5 @@ +package static_analysis.utils + import groovy.util.XmlParser import java.io.File