Compare commits
9 Commits
master
...
feature/MB
| Author | SHA1 | Date |
|---|---|---|
|
|
ab6a83aee0 | |
|
|
6df29f2101 | |
|
|
dca38422f3 | |
|
|
5c46386ebf | |
|
|
3cc63ffe5e | |
|
|
ec358728eb | |
|
|
78024ea1a6 | |
|
|
5e7a39d14d | |
|
|
e175e66e57 |
|
|
@ -13,7 +13,7 @@ repositories {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// android gradle plugin, required by custom plugin
|
// android gradle plugin, required by custom plugin
|
||||||
implementation("com.android.tools.build:gradle:4.0.1")
|
implementation("com.android.tools.build:gradle:7.1.3")
|
||||||
|
|
||||||
implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.10.0")
|
implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.10.0")
|
||||||
implementation("de.aaschmid:gradle-cpd-plugin:3.1")
|
implementation("de.aaschmid:gradle-cpd-plugin:3.1")
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package apigen
|
||||||
|
|
||||||
import org.gradle.api.Plugin
|
import org.gradle.api.Plugin
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.Task
|
|
||||||
import org.gradle.kotlin.dsl.create
|
import org.gradle.kotlin.dsl.create
|
||||||
import org.gradle.kotlin.dsl.dependencies
|
import org.gradle.kotlin.dsl.dependencies
|
||||||
import org.gradle.kotlin.dsl.repositories
|
import org.gradle.kotlin.dsl.repositories
|
||||||
|
|
@ -44,17 +43,23 @@ abstract class ApiGeneratorPlugin : Plugin<Project> {
|
||||||
|
|
||||||
protected fun Project.getExtension(): ApiGeneratorExtension = extensions.getByName(API_GENERATOR_EXT_NAME) as ApiGeneratorExtension
|
protected fun Project.getExtension(): ApiGeneratorExtension = extensions.getByName(API_GENERATOR_EXT_NAME) as ApiGeneratorExtension
|
||||||
|
|
||||||
private fun Project.createApiGeneratorTask(): Task = tasks.create(API_GENERATOR_CONFIG).doLast {
|
private fun Project.createApiGeneratorTask() = tasks.register(API_GENERATOR_CONFIG) {
|
||||||
|
|
||||||
val extension = getExtension()
|
val extension = getExtension()
|
||||||
|
|
||||||
val pathToApiSchemes = extension.pathToApiSchemes ?: throw IllegalStateException("Configure path to api schemes for api generator plugin")
|
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")
|
val outputLanguage = extension.outputLanguage ?: throw IllegalStateException("Configure output language code for api generator plugin")
|
||||||
|
|
||||||
|
outputs.files(files(pathToApiSchemes).asFileTree.files)
|
||||||
|
|
||||||
|
doLast {
|
||||||
javaexec {
|
javaexec {
|
||||||
main = "-jar"
|
mainClass.set("-jar")
|
||||||
workingDir = rootDir
|
workingDir = rootDir
|
||||||
args = listOfNotNull(
|
args = listOfNotNull(
|
||||||
|
"--add-opens",
|
||||||
|
"java.base/java.lang=ALL-UNNAMED",
|
||||||
|
"--add-opens",
|
||||||
|
"java.base/java.time=ALL-UNNAMED",
|
||||||
configurations.getByName("apiGenerator").asPath,
|
configurations.getByName("apiGenerator").asPath,
|
||||||
"generate-client-code",
|
"generate-client-code",
|
||||||
"--output-language",
|
"--output-language",
|
||||||
|
|
@ -68,9 +73,10 @@ abstract class ApiGeneratorPlugin : Plugin<Project> {
|
||||||
"--package-name",
|
"--package-name",
|
||||||
extension.outputPackageName,
|
extension.outputPackageName,
|
||||||
"--recreate_output_dirs",
|
"--recreate_output_dirs",
|
||||||
extension.recreateOutputDir.toString()
|
extension.recreateOutputDir.toString(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
package static_analysis.linters
|
package static_analysis.linters
|
||||||
|
|
||||||
import com.android.build.gradle.AppExtension
|
|
||||||
import com.android.build.gradle.AppPlugin
|
import com.android.build.gradle.AppPlugin
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.kotlin.dsl.findByType
|
|
||||||
import static_analysis.errors.AndroidLintError
|
import static_analysis.errors.AndroidLintError
|
||||||
import static_analysis.errors.StaticAnalysisError
|
import static_analysis.errors.StaticAnalysisError
|
||||||
import static_analysis.plugins.StaticAnalysisExtension
|
import static_analysis.plugins.StaticAnalysisExtension
|
||||||
|
|
@ -33,22 +31,10 @@ class AndroidLinter : Linter {
|
||||||
.flatten()
|
.flatten()
|
||||||
|
|
||||||
override fun setupForProject(project: Project, extension: StaticAnalysisExtension) {
|
override fun setupForProject(project: Project, extension: StaticAnalysisExtension) {
|
||||||
project.beforeEvaluate {
|
// Make sure to set lint options manually in modules gradle file
|
||||||
subprojects
|
// Otherwise you will get java.io.FileNotFoundException
|
||||||
.mapNotNull { it.extensions.findByType<AppExtension>() }
|
|
||||||
.first()
|
// See issue: https://github.com/TouchInstinct/BuildScripts/issues/310
|
||||||
.lintOptions.apply {
|
|
||||||
isAbortOnError = false
|
|
||||||
isCheckAllWarnings = true
|
|
||||||
isWarningsAsErrors = false
|
|
||||||
xmlReport = true
|
|
||||||
htmlReport = false
|
|
||||||
isCheckDependencies = true
|
|
||||||
disable("MissingConstraints", "VectorRaster")
|
|
||||||
xmlOutput = getLintReportFile()
|
|
||||||
lintConfig = file("${extension.buildScriptDir}/static_analysis_configs/lint.xml")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTaskNames(project: Project, buildType: String?): List<String> {
|
override fun getTaskNames(project: Project, buildType: String?): List<String> {
|
||||||
|
|
@ -62,11 +48,14 @@ class AndroidLinter : Linter {
|
||||||
.mapNotNull { subproject: Project ->
|
.mapNotNull { subproject: Project ->
|
||||||
subproject
|
subproject
|
||||||
.tasks
|
.tasks
|
||||||
.find { task -> task.name.contains(buildType, ignoreCase = true) && task.name.contains("lint") }
|
.filter { task ->
|
||||||
?.path
|
task.name.equals("lint${buildType}", ignoreCase = true)
|
||||||
|
|| task.name.equals("copy${buildType}AndroidLintReports", ignoreCase = true)
|
||||||
}
|
}
|
||||||
|
.map { it.path }
|
||||||
|
}
|
||||||
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Project.getLintReportFile() = file("${rootProject.buildDir}/reports/lint-report.xml")
|
private fun Project.getLintReportFile() = file("${rootProject.buildDir}/reports/lint-report.xml")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,24 @@ package static_analysis.linters
|
||||||
|
|
||||||
import io.gitlab.arturbosch.detekt.Detekt
|
import io.gitlab.arturbosch.detekt.Detekt
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.file.FileTree
|
||||||
import static_analysis.errors.DetektError
|
import static_analysis.errors.DetektError
|
||||||
import static_analysis.errors.StaticAnalysisError
|
import static_analysis.errors.StaticAnalysisError
|
||||||
import static_analysis.plugins.StaticAnalysisExtension
|
import static_analysis.plugins.StaticAnalysisExtension
|
||||||
import static_analysis.utils.getSources
|
import static_analysis.utils.getSources
|
||||||
|
import static_analysis.utils.runCommand
|
||||||
import static_analysis.utils.typedChildren
|
import static_analysis.utils.typedChildren
|
||||||
import static_analysis.utils.xmlParser
|
import static_analysis.utils.xmlParser
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class DetektLinter : Linter {
|
class DetektLinter : Linter {
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val TAG = "DetektLinter"
|
||||||
|
const val ONLY_DIFFS_FLAG = "only-diffs"
|
||||||
|
const val GET_GIT_DIFFS_COMMAND = "git diff --name-only --ignore-submodules"
|
||||||
|
}
|
||||||
|
|
||||||
override val name: String = "Detekt"
|
override val name: String = "Detekt"
|
||||||
|
|
||||||
override fun getErrors(project: Project): List<StaticAnalysisError> = xmlParser(project.getDetektReportFile())
|
override fun getErrors(project: Project): List<StaticAnalysisError> = xmlParser(project.getDetektReportFile())
|
||||||
|
|
@ -50,11 +59,39 @@ class DetektLinter : Linter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
source = getSources(extension.excludes)
|
val diffsBranch = properties[ONLY_DIFFS_FLAG] as? String
|
||||||
|
source = getSources(extension.excludes, diffsBranch, project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getSources(excludes: String, diffsBranch: String?, project: Project): FileTree = when (diffsBranch) {
|
||||||
|
null -> project.getSources(excludes)
|
||||||
|
else -> getGitDiffFiles(excludes, diffsBranch, project)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getGitDiffFiles(excludes: String, diffsBranch: String, project: Project): FileTree {
|
||||||
|
val getGitDiffsCommand = if (diffsBranch.isEmpty()) {
|
||||||
|
GET_GIT_DIFFS_COMMAND
|
||||||
|
} else {
|
||||||
|
GET_GIT_DIFFS_COMMAND.plus(" --merge-base $diffsBranch")
|
||||||
|
}
|
||||||
|
|
||||||
|
val gitDiffs = getGitDiffsCommand.runCommand()
|
||||||
|
|
||||||
|
if (gitDiffs.isNullOrEmpty()) {
|
||||||
|
project.logger.error("$TAG: Diffs are empty or specified branch or commit does not exists")
|
||||||
|
return project.files().asFileTree
|
||||||
|
}
|
||||||
|
|
||||||
|
val diffFiles = gitDiffs.lines()
|
||||||
|
.map { File(it) }
|
||||||
|
.filter { (it.extension == "kt" || it.extension == "java") && !excludes.contains(it.path) }
|
||||||
|
.toList()
|
||||||
|
|
||||||
|
return project.files(diffFiles).asFileTree
|
||||||
|
}
|
||||||
|
|
||||||
override fun getTaskNames(project: Project, buildType: String?): List<String> = listOf(":detekt")
|
override fun getTaskNames(project: Project, buildType: String?): List<String> = listOf(":detekt")
|
||||||
|
|
||||||
private fun Project.getDetektReportFile() = file("${rootProject.buildDir}/reports/detekt.xml")
|
private fun Project.getDetektReportFile() = file("${rootProject.buildDir}/reports/detekt.xml")
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package static_analysis.plugins
|
||||||
import com.android.build.gradle.AppExtension
|
import com.android.build.gradle.AppExtension
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.kotlin.dsl.getByType
|
import org.gradle.kotlin.dsl.getByType
|
||||||
|
import static_analysis.linters.AndroidLinter
|
||||||
import static_analysis.linters.CpdLinter
|
import static_analysis.linters.CpdLinter
|
||||||
import static_analysis.linters.DetektLinter
|
import static_analysis.linters.DetektLinter
|
||||||
import static_analysis.linters.Linter
|
import static_analysis.linters.Linter
|
||||||
|
|
@ -26,6 +27,23 @@ class StaticAnalysisAndroidPlugin : StaticAnalysisPlugin() {
|
||||||
buildVariant = applicationVariants.first { it.name.contains("Debug") }.name
|
buildVariant = applicationVariants.first { it.name.contains("Debug") }.name
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Task to run detekt checks.
|
||||||
|
*
|
||||||
|
* @param -Ponly-diffs <branch or commit> if specified, only files modified
|
||||||
|
* relative to this branch or commit will be checked. If specified without value
|
||||||
|
* then current uncommited changes will be checked. If not specified all source files will be checked.
|
||||||
|
* @see DetektLinter.getGitDiffFiles, 'git diff' for more info.
|
||||||
|
* */
|
||||||
|
project.tasks.register("detektAnalysis") {
|
||||||
|
val detektLinter = linters.find { it is DetektLinter }
|
||||||
|
?: throw IllegalStateException("DetektLinter not found")
|
||||||
|
|
||||||
|
setupStaticAnalysisTask(
|
||||||
|
linters = listOf(detektLinter),
|
||||||
|
buildVariant = applicationVariants.first { it.name.contains("Debug") }.name
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -34,8 +52,7 @@ class StaticAnalysisAndroidPlugin : StaticAnalysisPlugin() {
|
||||||
override fun createLinters(): List<Linter> = listOf(
|
override fun createLinters(): List<Linter> = listOf(
|
||||||
DetektLinter(),
|
DetektLinter(),
|
||||||
CpdLinter(),
|
CpdLinter(),
|
||||||
//TODO temporary disable Android Linter to avoid FileNotFoundException when generating report
|
AndroidLinter()
|
||||||
//AndroidLinter()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package static_analysis.utils
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
fun String.runCommand(
|
||||||
|
directoryToExecute: File? = null,
|
||||||
|
timeoutSec: Long = 30,
|
||||||
|
): String? {
|
||||||
|
return try {
|
||||||
|
val parts = this.split("\\s".toRegex())
|
||||||
|
val process = ProcessBuilder(*parts.toTypedArray())
|
||||||
|
.directory(directoryToExecute)
|
||||||
|
.redirectOutput(ProcessBuilder.Redirect.PIPE)
|
||||||
|
.redirectError(ProcessBuilder.Redirect.PIPE)
|
||||||
|
.start()
|
||||||
|
|
||||||
|
process.waitFor(timeoutSec, TimeUnit.SECONDS)
|
||||||
|
process.inputStream.bufferedReader().readText()
|
||||||
|
} catch(e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
android {
|
||||||
|
lint {
|
||||||
|
abortOnError false
|
||||||
|
checkAllWarnings true
|
||||||
|
warningsAsErrors false
|
||||||
|
checkDependencies true
|
||||||
|
htmlReport false
|
||||||
|
textReport false
|
||||||
|
xmlReport true
|
||||||
|
xmlOutput file("${rootProject.buildDir}/reports/lint-report.xml")
|
||||||
|
lintConfig file("${rootProject.ext["buildScriptsDir"]}/static_analysis_configs/lint.xml")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
import groovy.json.JsonSlurper
|
import groovy.json.JsonSlurper
|
||||||
import groovy.xml.MarkupBuilder
|
import groovy.xml.MarkupBuilder
|
||||||
|
|
||||||
task stringGenerator {
|
tasks.register('stringGenerator') {
|
||||||
generate(android.languageMap, project)
|
Map<String, String> sources = android.languageMap
|
||||||
|
|
||||||
|
outputs.files(sources)
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
generate(sources, project)
|
||||||
println("Strings generated!")
|
println("Strings generated!")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private def generate(Map<String, String> sources, Project project) {
|
private def generate(Map<String, String> sources, Project project) {
|
||||||
if (sources == null || sources.isEmpty()) {
|
if (sources == null || sources.isEmpty()) {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@
|
||||||
<!--All activities should have locked orientation-->
|
<!--All activities should have locked orientation-->
|
||||||
<issue id="LockedOrientationActivity" severity="ignore" />
|
<issue id="LockedOrientationActivity" severity="ignore" />
|
||||||
|
|
||||||
|
<!-- TODO: Update Timber version. See this issue: https://github.com/JakeWharton/timber/issues/408 -->
|
||||||
|
<issue id="WrongTimberUsageDetector" severity="ignore" />
|
||||||
|
|
||||||
<issue id="AllowAllHostnameVerifier" severity="error" />
|
<issue id="AllowAllHostnameVerifier" severity="error" />
|
||||||
<issue id="InvalidUsesTagAttribute" severity="error" />
|
<issue id="InvalidUsesTagAttribute" severity="error" />
|
||||||
<issue id="MissingIntentFilterForMediaSearch" severity="error" />
|
<issue id="MissingIntentFilterForMediaSearch" severity="error" />
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue