Build checks Gradle plugin#
This plugin verifies common build problems with environment and project configuration.
Getting started#
Apply the plugin in a root build script or in an Android application module:
plugins {
id("com.avito.android.build-checks")
}
Setup plugins
In the settings.gradle
:
pluginManagement {
repositories {
mavenCentral()
}
resolutionStrategy {
eachPlugin {
String pluginId = requested.id.id
if (pluginId.startsWith("com.avito.android")) {
def artifact = pluginId.replace("com.avito.android.", "")
useModule("com.avito.android:$artifact:$avitoToolsVersion")
}
}
}
}
avitoToolsVersion
could be exact version, or property in project's gradle.properties
.
The latest version could be found on project's release page.
build.gradle.kts
buildChecks {
androidSdk {
version(
compileSdkVersion = 29,
revision = 5
)
}
}
build.gradle
buildChecks {
androidSdk {
version(29, 5)
}
uniqueRClasses {
enabled = false
}
}
That's all for a configuration. Run it manually to verify that it works:
./gradlew checkBuildEnvironment
The plugin will run it automatically on every build.
Configuration#
Enable single check#
build.gradle.kts
buildChecks {
enableByDefault = false
androidSdk {
version(
compileSdkVersion = 29,
revision = 5
)
}
}
build.gradle
buildChecks {
enableByDefault = false
androidSdk {
version(29, 5)
}
}
Disable single check#
build.gradle.kts
buildChecks {
androidSdk {
enabled = false
}
}
build.gradle
buildChecks {
androidSdk {
enabled = false
}
}
Disable all checks#
build.gradle.kts
buildChecks {
enableByDefault = false
}
build.gradle
buildChecks {
enableByDefault = false
}
Disable plugin#
To completely disable the plugin add a Gradle property:
avito.build-checks.enabled=false
Checks#
Common build checks#
These checks are available in a root project's buildscript.
See also Android application checks.
Android SDK version#
Android build tools uses android.jar ($ANDROID_HOME/platforms/android-<compileSdkVersion>/android.jar
).
The version can be specified only without a revision (#117789774).
Different revisions lead to Gradle remote cache misses.
This check forces the same revision:
build.gradle.kts
buildChecks {
androidSdk {
version(
compileSdkVersion = 29,
revision = 5
)
// You can define multiple versions if modules use them
version(
compileSdkVersion = 30,
revision = 3
)
}
}
build.gradle
buildChecks {
androidSdk {
version(29, 5)
}
}
macOS localhost lookup#
On macOs java.net.InetAddress#getLocalHost()
invocation can last up to 5 seconds instead of milliseconds
(thoeni.io/post/macos-sierra-java). Gradle has
a workaround but it works only inside Gradle's code.
To diagnose the problem manually use thoeni/inetTester.
To fix the problem use this workaround:
- Find your computer's name - Find your computer's name and network address
- Add it to
/etc/hosts
config:
127.0.0.1 localhost <your_host_name>.local
::1 localhost <your_host_name>.local
- Reboot the computer
- Check again by thoeni/inetTester
This check automatically detects the issue:
build.gradle.kts
buildChecks {
macOSLocalhost { }
}
build.gradle
buildChecks {
macOSLocalhost { }
}
Gradle properties#
Warning
This check is deprecated and will be removed.
Disclaimer
The text below contains Avito specific details
This check detects if you override Gradle project property by command-line. It sends mismatches to statsd. This information helps to see frequently changed propeties that can lead to remote cache misses.
build.gradle.kts
buildChecks {
gradleProperties {
enabled = true // disabled by default
}
}
build.gradle
buildChecks {
gradleProperties {
enabled = true // disabled by default
}
}
Android application checks#
These checks are available in an Android application's buildscript.
Each application can have specific settings.
Unique R classes#
If two Android libraries use the same package, their R classes will be merged. While merging, it can unexpectedly override
resources (#175316324). It happens even
with android.namespacedRClass
.
To forbid merged R files use this check:
build.gradle.kts
plugins {
id("com.avito.android.build-checks")
}
buildChecks {
uniqueRClasses { } // enabled by default
}
build.gradle
plugins {
id("com.avito.android.build-checks")
}
buildChecks {
uniqueRClasses { } // enabled by default
}
See also android.uniquePackageNames
check. In AGP 4.1 it provides similar but less complete contract.
You can suppress errors for a specific package:
build.gradle.kts
buildChecks {
uniqueRClasses {
allowedNonUniquePackageNames.addAll(listOf(
"androidx.test", // Default from ManifestMerger #151171905
"androidx.test.espresso", // Won't fix: https://issuetracker.google.com/issues/176002058
"androidx.navigation.ktx" // Fixed in 2.2.1: https://developer.android.com/jetpack/androidx/releases/navigation#2.2.1
))
}
}
Unique application resources#
From Android library - considerations:
The build tools merge resources from a library module with those of a dependent app module.
If a given resource ID is defined in both modules, the resource from the app is used.
If conflicts occur between multiple AAR libraries, then the resource from the library listed first in the dependencies list is used.
uniqueAppResources
ensures that resources in application are unique and won't be overridden implicitly.
build.gradle.kts
Root module:
plugins {
id("com.avito.android.impact")
}
Application module:
plugins {
id("com.avito.android.build-checks")
}
buildChecks {
uniqueAppResources {} // disabled by default
}
build.gradle
Root module:
plugins {
id("com.avito.android.impact")
}
Application module:
plugins {
id("com.avito.android.build-checks")
}
buildChecks {
uniqueAppResources {} // disabled by default
}
To avoid resource conflicts, consider using a prefix (android.resourcePrefix
) or other consistent naming scheme.
Ignoring duplicates#
buildChecks {
uniqueAppResources {
// Resource types: string, dimen, bool, layout, drawable, ...
ignoredResourceTypes.add("string")
// Specific resources
ignoredResource("string", "title")
ignoredResource("dimen", "max_height")
}
}
Known issues#
- Requires impact analysis that slows project configuration
- Disabled by default due to possible false positive cases. Usually, it requires to configure ignored resources.
- Don't compare values, only resource identifiers. Reported duplicates can have the same content.
- Detects only project modules without binary dependencies. Don't know how to deal with massive false positive duplicates for widely used libraries (androidx and similar ones).
- Some resource types are not supported because the issue is not confirmed for them. These are
id
,attr
,styleable
.