Skip to content

Commit

Permalink
remove system properties reading in :gradle:android (#568)
Browse files Browse the repository at this point in the history
* remove system properties reading in :gradle:android
* remove compileSdkVersion mentions from build-check docs
  • Loading branch information
dsvoronin authored Sep 7, 2020
1 parent f43ba66 commit 6fe0760
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 217 deletions.
18 changes: 0 additions & 18 deletions docs/content/docs/projects/BuildChecks.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,6 @@ plugins {

{{%plugins-setup%}}

Some checks will require settings to work properly.
You'll get an error about missing settings:

```text
> ./gradlew
A problem occurred configuring root project
> buildChecks.androidSdk.compileSdkVersion must be set
```

After adding missing properties you will get something like this:

{{< tabs "build checks example" >}}
{{< tab "Kotlin" >}}

Expand All @@ -39,7 +27,6 @@ After adding missing properties you will get something like this:
```kotlin
buildChecks {
androidSdk {
compileSdkVersion = 29
revision = 4
}
javaVersion {
Expand All @@ -59,7 +46,6 @@ buildChecks {
```groovy
buildChecks {
androidSdk {
compileSdkVersion = 29
revision = 4
}
javaVersion {
Expand Down Expand Up @@ -149,7 +135,6 @@ buildChecks {
enableByDefault = false

androidSdk {
compileSdkVersion = 29
revision = 4
}
}
Expand All @@ -164,7 +149,6 @@ buildChecks {
enableByDefault = false
androidSdk {
compileSdkVersion = 29
revision = 4
}
}
Expand Down Expand Up @@ -221,7 +205,6 @@ Different revisions lead to Gradle remote cache misses. This check forces the sa
```kotlin
buildChecks {
androidSdk {
compileSdkVersion = 29
revision = 4
}
}
Expand All @@ -234,7 +217,6 @@ buildChecks {
```groovy
buildChecks {
androidSdk {
compileSdkVersion = 29
revision = 4
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,107 +1,88 @@
package com.avito.android

import com.avito.utils.ExistingDirectory
import com.avito.utils.ExistingFile
import com.avito.utils.ProcessRunner
import org.funktionale.tries.Try
import org.gradle.api.Project
import java.io.File
import java.util.Properties
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract

/**
* Используется для доступа к ресурсам SDK(executables, чтение параметров) из build-скриптов
*/
@Suppress("unused")
val Project.androidHome: String
get() = System.getenv("ANDROID_HOME")
?: androidHomeFromLocalProperties(rootProject.file("local.properties")) { logger.error(it) }
?: error("Can't resolve ANDROID_HOME")

val Project.androidSdk: AndroidSdk
get() = AndroidSdk(this, ProcessRunner.Real())

class AndroidSdk(
private val project: Project,
private val processRunner: ProcessRunner
) : ApkSigner, Aapt {
) {

@Suppress("unused")
private val targetSdkVersion: Int
get() = requireNotNull(System.getProperty("targetSdkVersion").toIntOrNull()) {
"targetSdkVersion system property should be set"
private val buildToolsVersion: String
get() {
require(project.isAndroid()) { "Trying to get android.buildToolsVersion object on non-android project: ${project.path}" }
return project.androidBaseExtension.buildToolsVersion
}

private val compileSdkVersion: Int
get() = requireNotNull(System.getProperty("compileSdkVersion").toIntOrNull()) {
"compileSdkVersion system property should be set"
}


private val buildToolsVersion: String
get() {
val value = System.getProperty("buildToolsVersion")
require(value.hasContent()) { "buildToolsVersion env must be set" }
return value
require(project.isAndroid()) { "Trying to get android.compileSdkVersion object on non-android project: ${project.path}" }
return requireNotNull(
value = project.androidBaseExtension.compileSdkVersion,
lazyMessage = { "compileSdkVersion is null for project: ${project.path}" }).apply {
if (this.isBlank()) {
error("compileSdkVersion not set for project: ${project.path}")
}
}.toInt()
}

private val buildToolsPath: ExistingDirectory
/**
* it's not part of android sdk, provided here for convenience
*/
val keytool = KeyTool(processRunner)

val androidHome: ExistingDirectory
get() {
val dir = File(androidHome.dir, "/build-tools/$buildToolsVersion")
require(dir.exists()) {
"""========= ERROR =========
Android Build tools are not found in ${dir.path}
Please install it or update.
""".trimIndent()
}
val dir = System.getenv("ANDROID_HOME")
?: androidHomeFromLocalProperties(
localPropertiesLocation = project.rootProject.file("local.properties"),
logger = { project.logger.error(it) })
?: error("Can't resolve ANDROID_HOME")
return ExistingDirectory.Impl(dir)
}

private val apkSigner: ApkSigner
get() = ApkSigner.Impl(buildToolsPath, processRunner)

private val aapt: Aapt
get() = Aapt.Impl(buildToolsPath, processRunner)

private val keytool = KeyTool(processRunner)

val androidHome: ExistingDirectory
get() = ExistingDirectory.Impl(project.androidHome)
val aapt: Aapt
get() = Aapt.Impl(buildToolsPath(buildToolsVersion), processRunner)

val androidJar: File
get() {
val file = File(platformDir, "android.jar")
val file = File(platformDir(compileSdkVersion), "android.jar")
require(file.exists()) {
sdkNotFoundMessage(file.path)
}
return file
}

val platformSourceProperties: File
get() = platformSourceProperties()
get() {
val file = File(platformDir(compileSdkVersion), "source.properties")
require(file.exists()) {
sdkNotFoundMessage(file.path)
}
return file
}

fun platformSourceProperties(compileSdkVersion: Int = this.compileSdkVersion): File {
val file = File(platformDir(compileSdkVersion), "source.properties")
require(file.exists()) {
sdkNotFoundMessage(file.path)
private fun buildToolsPath(buildToolsVersion: String): ExistingDirectory {
val dir = File(androidHome.dir, "/build-tools/$buildToolsVersion")
require(dir.exists()) {
"""========= ERROR =========
Android Build tools are not found in ${dir.path}
Please install it or update.
""".trimIndent()
}
return file
return ExistingDirectory.Impl(dir)
}

private fun platformDir(compileSdkVersion: Int = this.compileSdkVersion): File {
private fun platformDir(compileSdkVersion: Int): File {
return File(androidHome.dir, "platforms/android-$compileSdkVersion")
}

private val platformDir: File
get() = platformDir(compileSdkVersion)

override fun getApkSha1(apk: ExistingFile): Try<String> = apkSigner.getApkSha1(apk)

override fun getPackageName(apk: File): Try<String> = aapt.getPackageName(apk)

fun getBundleSha1(aab: ExistingFile): Try<String> = keytool.getJarSha1(aab)

private fun sdkNotFoundMessage(message: String): String {
return """========= ERROR =========
Android SDK tools are not found.
Expand All @@ -112,16 +93,8 @@ class AndroidSdk(
}

/**
* Используем в тестах, когда по какой-то причине не удалось зарезолвить env ANDROID_HOME
* Нужно только в тех местах где нет доступа к project, в нашем случае это на этапе создания android проекта для
* Gradle Test kit
*
* Все равно остается вариант при котором тесты не заработают:
* local.properties первый раз генерируется во время открытия проекта avito-android в Android Studio
* и не хранится под version control, поэтому если у разработчика не установлена ANDROID_HOME и он открывает
* напрямую проект в любой IDE, его ждет ошибка про "no sdk found"
*
* @return path до Android Sdk если получилось найти таким способом
* Used in tests, when for any reason ANDROID_HOME environment variable was not resolved
* Required in places where is no access to Project, mostly on Gradle Test Kit project creation
*/
fun androidHomeFromLocalPropertiesFallback(): String {
val env = System.getenv("ANDROID_HOME")
Expand All @@ -146,14 +119,3 @@ private fun androidHomeFromLocalProperties(
null
}
}

@OptIn(ExperimentalContracts::class)
private fun String?.hasContent(): Boolean {
contract {
returns(true) implies (this@hasContent != null)
}

if (isNullOrBlank()) return false
if (this == "null") return false
return true
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ open class BuildChecksExtension {

open class AndroidSdk : Check(), RequireParameters {

@Deprecated("not used anymore, remove after 2020.19")
var compileSdkVersion: Int = -1
var revision: Int = -1

override fun validate() {
check(compileSdkVersion > 0) { "$extensionName.androidSdk.compileSdkVersion must be set" }
check(revision > 0) { "$extensionName.androidSdk.minRevision must be set" }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ open class BuildParamCheckPlugin : Plugin<Project> {
registerRequiredTasks(project, checks)

if (checks.hasInstance<Check.JavaVersion>()) {
checkJavaVersion(checks.getInstance<Check.JavaVersion>())
checkJavaVersion(checks.getInstance())
}
if (checks.hasInstance<Check.GradleProperties>()) {
checkGradleProperties(project)
Expand Down Expand Up @@ -81,7 +81,6 @@ open class BuildParamCheckPlugin : Plugin<Project> {
description =
"Checks sdk version in docker against local one to prevent build cache misses"

compileSdkVersion.set(check.compileSdkVersion)
revision.set(check.revision)
// don't run task if it is already compared hashes and it's ok
// task will be executed next time if either local jar or docker jar(e.g. inputs) changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ import java.io.File

abstract class CheckAndroidSdkVersionTask : DefaultTask() {

@get:Input
abstract val compileSdkVersion: Property<Int>

@get:Input
abstract val revision: Property<Int>

Expand Down Expand Up @@ -55,9 +52,8 @@ abstract class CheckAndroidSdkVersionTask : DefaultTask() {
}

private fun localRevision(): Int {
val sourceProperties: File = project.androidSdk.platformSourceProperties(compileSdkVersion.get())
val sourceProperties: File = project.androidSdk.platformSourceProperties
return requireNotNull(sourceProperties.loadProperties().getProperty("Pkg.Revision", null))
.toInt()
}

}
Loading

0 comments on commit 6fe0760

Please sign in to comment.