385 lines
14 KiB
Groovy
385 lines
14 KiB
Groovy
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
|
|
|
import io.gitlab.arturbosch.detekt.Detekt
|
|
import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask
|
|
import org.gradle.internal.logging.text.StyledTextOutput.Style
|
|
import org.gradle.internal.logging.text.StyledTextOutputFactory
|
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|
import static org.gradle.api.tasks.testing.TestResult.ResultType
|
|
|
|
buildscript {
|
|
repositories {
|
|
gradle.mozconfig.substs.GRADLE_MAVEN_REPOSITORIES.each { repository ->
|
|
maven {
|
|
url = repository
|
|
if (gradle.mozconfig.substs.ALLOW_INSECURE_GRADLE_REPOSITORIES) {
|
|
allowInsecureProtocol = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
classpath libs.tools.androidgradle
|
|
}
|
|
}
|
|
|
|
plugins {
|
|
alias(libs.plugins.detekt)
|
|
alias(libs.plugins.kotlin.android) apply false
|
|
alias(libs.plugins.kotlin.compose) apply false
|
|
alias(libs.plugins.ksp)
|
|
}
|
|
|
|
allprojects {
|
|
repositories {
|
|
gradle.mozconfig.substs.GRADLE_MAVEN_REPOSITORIES.each { repository ->
|
|
maven {
|
|
url = repository
|
|
if (gradle.mozconfig.substs.ALLOW_INSECURE_GRADLE_REPOSITORIES) {
|
|
allowInsecureProtocol = true
|
|
}
|
|
}
|
|
}
|
|
|
|
maven {
|
|
url = "${gradle.mozconfig.topobjdir}/gradle/maven"
|
|
}
|
|
}
|
|
|
|
// Enable Kotlin warnings as errors for all modules
|
|
tasks.withType(KotlinCompile).configureEach {
|
|
compilerOptions.allWarningsAsErrors = true
|
|
}
|
|
}
|
|
|
|
subprojects {
|
|
apply plugin: 'jacoco'
|
|
|
|
// Prevent some dependencies used by Fenix/Focus from being used in AC.
|
|
project.configurations.all {
|
|
exclude group: 'com.adjust.sdk', module: 'adjust-android'
|
|
exclude group: 'io.mockk', module: 'mockk'
|
|
}
|
|
|
|
project.configurations.configureEach {
|
|
// Dependencies can't depend on a different major version of Glean than A-C itself.
|
|
resolutionStrategy.eachDependency { details ->
|
|
if (details.requested.group == 'org.mozilla.telemetry'
|
|
&& details.requested.name.contains('glean') ) {
|
|
def requested = details.requested.version.tokenize(".")
|
|
def defined = libs.versions.mozilla.glean.get().tokenize(".")
|
|
// Check the major version
|
|
if (requested[0] != defined[0]) {
|
|
throw new AssertionError("Cannot resolve to a single Glean version. Requested: ${details.requested.version}, A-C uses: ${libs.versions.mozilla.glean.get()}")
|
|
} else {
|
|
// Enforce that all (transitive) dependencies are using the defined Glean version
|
|
details.useVersion libs.versions.mozilla.glean.get()
|
|
}
|
|
}
|
|
}
|
|
|
|
resolutionStrategy.capabilitiesResolution.withCapability("org.mozilla.telemetry:glean-native") {
|
|
def toBeSelected = candidates.find { it.id instanceof ModuleComponentIdentifier && it.id.module.contains('geckoview') }
|
|
if (toBeSelected != null) {
|
|
select(toBeSelected)
|
|
}
|
|
because 'use GeckoView Glean instead of standalone Glean'
|
|
}
|
|
}
|
|
|
|
if (gradle.hasProperty('localProperties.dependencySubstitutions.geckoviewTopsrcdir')) {
|
|
if (gradle.hasProperty('localProperties.dependencySubstitutions.geckoviewTopobjdir')) {
|
|
ext.topobjdir = gradle."localProperties.dependencySubstitutions.geckoviewTopobjdir"
|
|
}
|
|
ext.topsrcdir = gradle."localProperties.dependencySubstitutions.geckoviewTopsrcdir"
|
|
apply from: "${topsrcdir}/substitute-local-geckoview.gradle"
|
|
}
|
|
|
|
afterEvaluate {
|
|
if (it.hasProperty('android')) {
|
|
jacoco {
|
|
toolVersion = libs.versions.jacoco.get()
|
|
}
|
|
|
|
// Format test output
|
|
tasks.matching {it instanceof Test}.configureEach() {
|
|
systemProperty "robolectric.logging", "stdout"
|
|
systemProperty "logging.test-mode", "true"
|
|
systemProperty "javax.net.ssl.trustStoreType", "JKS"
|
|
|
|
testLogging.events = []
|
|
|
|
beforeSuite { descriptor ->
|
|
if (descriptor.getClassName() != null) {
|
|
println("\nSUITE: " + descriptor.getClassName())
|
|
}
|
|
}
|
|
|
|
beforeTest { descriptor ->
|
|
println(" TEST: " + descriptor.getName())
|
|
}
|
|
|
|
onOutput { descriptor, event ->
|
|
it.logger.lifecycle(" " + event.message.trim())
|
|
}
|
|
|
|
afterTest { descriptor, result ->
|
|
switch (result.getResultType()) {
|
|
case ResultType.SUCCESS:
|
|
println(" SUCCESS")
|
|
break
|
|
|
|
case ResultType.FAILURE:
|
|
def testId = descriptor.getClassName() + "." + descriptor.getName()
|
|
println(" TEST-UNEXPECTED-FAIL | " + testId + " | " + result.getException())
|
|
break
|
|
|
|
case ResultType.SKIPPED:
|
|
println(" SKIPPED")
|
|
break
|
|
}
|
|
it.logger.lifecycle("")
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
lintChecks project(':tooling-lint')
|
|
}
|
|
|
|
kotlin {
|
|
jvmToolchain(config.jvmTargetCompatibility)
|
|
}
|
|
|
|
android {
|
|
// We can't have one baseline file at the root of android-components because
|
|
// this is not a project module and we would have to coordinate every module to
|
|
// merge baselines.
|
|
lint {
|
|
baseline = file("${projectDir}/lint-baseline.xml")
|
|
}
|
|
|
|
buildToolsVersion gradle.mozconfig.substs.ANDROID_BUILD_TOOLS_VERSION
|
|
|
|
testOptions {
|
|
unitTests {
|
|
includeAndroidResources = true
|
|
}
|
|
}
|
|
|
|
// https://issuetracker.google.com/issues/379732901
|
|
packaging {
|
|
resources {
|
|
excludes += ['META-INF/LICENSE.md', 'META-INF/LICENSE-notice.md',
|
|
'META-INF/versions/9/OSGI-INF/MANIFEST.MF']
|
|
}
|
|
}
|
|
|
|
androidResources {
|
|
ignoreAssetsPattern = "manifest.template.json"
|
|
}
|
|
}
|
|
|
|
if (project.hasProperty("coverage") && project.name != "support-test") {
|
|
android.buildTypes.all { buildType ->
|
|
tasks.withType(Test).configureEach() {
|
|
jacoco {
|
|
includeNoLocationClasses = true
|
|
excludes = ['jdk.internal.*']
|
|
}
|
|
|
|
finalizedBy { "jacoco${buildType.name.capitalize()}TestReport" }
|
|
}
|
|
|
|
tasks.register("jacoco${buildType.name.capitalize()}TestReport", JacocoReport) {
|
|
reports {
|
|
xml.required = true
|
|
html.required = true
|
|
}
|
|
|
|
def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*',
|
|
'**/*Test*.*', 'android/**/*.*', '**/*$[0-9].*']
|
|
def kotlinDebugTree = fileTree(dir: "$project.layout.buildDirectory/tmp/kotlin-classes/${buildType.name}", excludes: fileFilter)
|
|
def javaDebugTree = fileTree(dir: "$project.layout.buildDirectory/intermediates/classes/${buildType.name}", excludes: fileFilter)
|
|
def mainSrc = "$project.projectDir/src/main/java"
|
|
|
|
sourceDirectories.setFrom(files([mainSrc]))
|
|
classDirectories.setFrom(files([kotlinDebugTree, javaDebugTree]))
|
|
getExecutionData().setFrom(fileTree(project.layout.buildDirectory).include([
|
|
"jacoco/test${buildType.name.capitalize()}UnitTest.exec"
|
|
]))
|
|
}
|
|
}
|
|
|
|
android {
|
|
buildTypes {
|
|
debug {
|
|
testCoverageEnabled true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.withType(KotlinCompile).configureEach {
|
|
// Translate Kotlin messages like "w: ..." and "e: ..." into
|
|
// "...: warning: ..." and "...: error: ...", to make Treeherder understand.
|
|
def listener = {
|
|
if (it.startsWith("e: warnings found")) {
|
|
return
|
|
}
|
|
|
|
if (it.startsWith('w: ') || it.startsWith('e: ')) {
|
|
def matches = (it =~ /([ew]): (.+):(\d+):(\d+) (.*)/)
|
|
if (!matches) {
|
|
logger.quiet "kotlinc message format has changed!"
|
|
if (it.startsWith('w: ')) {
|
|
// For warnings, don't continue because we don't want to throw an
|
|
// exception. For errors, we want the exception so that the new error
|
|
// message format gets translated properly.
|
|
return
|
|
}
|
|
}
|
|
def (_, type, file, line, column, message) = matches[0]
|
|
type = (type == 'w') ? 'warning' : 'error'
|
|
// Use logger.lifecycle, which does not go through stderr again.
|
|
logger.lifecycle "$file:$line:$column: $type: $message"
|
|
}
|
|
} as StandardOutputListener
|
|
|
|
doFirst {
|
|
logging.addStandardErrorListener(listener)
|
|
}
|
|
doLast {
|
|
logging.removeStandardErrorListener(listener)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (findProject(":geckoview") == null) {
|
|
// Avoid adding this task if it already exists in a different root project.
|
|
tasks.register("clean", Delete) {
|
|
delete rootProject.layout.buildDirectory
|
|
}
|
|
}
|
|
|
|
detekt {
|
|
input = files("$projectDir/components", "$projectDir/buildSrc", "$projectDir/samples")
|
|
config = files("$projectDir/config/detekt.yml")
|
|
baseline = file("$projectDir/config/detekt-baseline.xml")
|
|
|
|
reports {
|
|
html {
|
|
enabled = true
|
|
destination = file("$projectDir/build/reports/detekt.html")
|
|
}
|
|
xml {
|
|
enabled = false
|
|
}
|
|
txt {
|
|
enabled = false
|
|
}
|
|
}
|
|
}
|
|
|
|
tasks.withType(Detekt).configureEach() {
|
|
// Custom detekt rules should be built before.
|
|
// See https://detekt.dev/docs/introduction/extensions#pitfalls
|
|
dependsOn(":tooling-detekt:assemble")
|
|
|
|
autoCorrect = true
|
|
|
|
exclude "**/build.gradle.kts"
|
|
exclude "**/build/**"
|
|
exclude "**/docs/**"
|
|
exclude "**/resources/**"
|
|
exclude "**/src/androidTest/**"
|
|
exclude "**/src/iosTest/**"
|
|
exclude "**/src/main/assets/extensions/**"
|
|
exclude "**/src/test/**"
|
|
exclude "**/test/src/**"
|
|
exclude "**/tmp/**"
|
|
exclude "**/tooling/fetch-tests/**"
|
|
}
|
|
|
|
// Apply same path exclusions as for the main task
|
|
tasks.withType(DetektCreateBaselineTask).configureEach() {
|
|
dependsOn(":browser-icons:updateBuiltInExtensionVersion")
|
|
dependsOn(":feature-accounts:updateBuiltInExtensionVersion")
|
|
dependsOn(":feature-readerview:updateBuiltInExtensionVersion")
|
|
dependsOn(":feature-search:updateAdsExtensionVersion")
|
|
dependsOn(":feature-search:updateCookiesExtensionVersion")
|
|
dependsOn(":samples-browser:updateBorderifyExtensionVersion")
|
|
dependsOn(":samples-browser:updateTestExtensionVersion")
|
|
dependsOn(":samples-compose-browser:updateBorderifyExtensionVersion")
|
|
dependsOn(":samples-compose-browser:updateTestExtensionVersion")
|
|
dependsOn(":tooling-detekt:assemble")
|
|
|
|
exclude "**/build.gradle.kts"
|
|
exclude "**/build/**"
|
|
exclude "**/docs/**"
|
|
exclude "**/resources/**"
|
|
exclude "**/src/androidTest/**"
|
|
exclude "**/src/iosTest/**"
|
|
exclude "**/src/main/assets/extensions/**"
|
|
exclude "**/src/test/**"
|
|
exclude "**/test/src/**"
|
|
exclude "**/tmp/**"
|
|
exclude "**/tooling/fetch-tests/**"
|
|
}
|
|
|
|
configurations {
|
|
ktlint
|
|
}
|
|
|
|
dependencies {
|
|
ktlint(libs.ktlint) {
|
|
attributes {
|
|
attribute(Bundling.BUNDLING_ATTRIBUTE, getObjects().named(Bundling, Bundling.EXTERNAL))
|
|
}
|
|
}
|
|
detektPlugins project(":tooling-detekt")
|
|
}
|
|
|
|
tasks.register("ktlint", JavaExec) {
|
|
group = "verification"
|
|
description = "Check Kotlin code style."
|
|
classpath = configurations.ktlint
|
|
mainClass.set("com.pinterest.ktlint.Main")
|
|
args "components/**/*.kt"
|
|
args "samples/**/*.kt"
|
|
args "!**/build/**/*.kt"
|
|
args "buildSrc/**/*.kt"
|
|
args "--baseline=ktlint-baseline.xml"
|
|
args "--reporter=json,output=build/reports/ktlint/ktlint.json"
|
|
args "--reporter=plain"
|
|
}
|
|
|
|
tasks.register("ktlintFormat", JavaExec) {
|
|
group = "formatting"
|
|
description = "Fix Kotlin code style deviations."
|
|
classpath = configurations.ktlint
|
|
mainClass.set("com.pinterest.ktlint.Main")
|
|
args "-F"
|
|
args "components/**/*.kt"
|
|
args "samples/**/*.kt"
|
|
args "!**/build/**/*.kt"
|
|
args "buildSrc/**/*.kt"
|
|
args "--baseline=ktlint-baseline.xml"
|
|
args "--reporter=json,output=build/reports/ktlint/ktlintFormat.json"
|
|
args "--reporter=plain"
|
|
jvmArgs("--add-opens", "java.base/java.lang=ALL-UNNAMED")
|
|
}
|
|
|
|
tasks.register("listRepositories") {
|
|
def reposData = project.provider {
|
|
project.repositories.collect { repo ->
|
|
[name: repo.name, url: repo.url.toString()]
|
|
}
|
|
}
|
|
doLast {
|
|
println "Repositories:"
|
|
reposData.get().each { println "Name: " + it.name + "; url: " + it.url }
|
|
}
|
|
}
|