import org.gradle.plugins.ide.idea.model.IdeaModel buildscript { apply from: 'dependencies.gradle' repositories { google() mavenCentral() gradlePluginPortal() maven { url "https://plugins.gradle.org/m2/" } } dependencies { gradle classpath 'com.android.tools.build:gradle:7.3.0' classpath 'net.ltgt.gradle:gradle-errorprone-plugin:2.0.2' classpath 'com.netflix.nebula:gradle-aggregate-javadocs-plugin:3.0.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" classpath "com.github.ben-manes:gradle-versions-plugin:0.42.0" classpath "com.diffplug.spotless:spotless-plugin-gradle:6.9.1" } } allprojects { repositories { google() mavenCentral() gradlePluginPortal() } group = "org.robolectric" version = thisVersion } apply plugin: 'idea' apply plugin: 'com.github.ben-manes.versions' project.ext.configAnnotationProcessing = [] project.afterEvaluate { def ideaProject = rootProject.extensions.getByType(IdeaModel).project ideaProject.ipr.withXml { provider -> def compilerConfiguration = provider.asNode().component.find { it.'@name' == 'CompilerConfiguration' } // prevent compiler from complaining about duplicate classes... def excludeFromCompile = compilerConfiguration.appendNode 'excludeFromCompile' configAnnotationProcessing.each { Project subProject -> excludeFromCompile.appendNode('directory', [url: "file://${subProject.buildDir}/classes/java/main/generated", includeSubdirectories: "true"]) } // replace existing annotationProcessing tag with a new one... compilerConfiguration.annotationProcessing.replaceNode { annotationProcessing { configAnnotationProcessing.each { Project subProject -> profile(name: "${subProject.name}_main", enabled: "true") { module(name: "${subProject.name}_main") option(name: "org.robolectric.annotation.processing.shadowPackage", value: subProject.shadows.packageName) processor(name: "org.robolectric.annotation.processing.RobolectricProcessor") processorPath(useClasspath: "false") { def processorRuntimeCfg = project.project(":processor").configurations['runtime'] processorRuntimeCfg.allArtifacts.each { artifact -> entry(name: artifact.file) } processorRuntimeCfg.files.each { file -> entry(name: file) } } } } } } } } apply plugin: 'nebula-aggregate-javadocs' rootProject.gradle.projectsEvaluated { rootProject.tasks['aggregateJavadocs'].failOnError = false } gradle.projectsEvaluated { def headerHtml = "" project.allprojects { p -> p.tasks.withType(Javadoc) { options { noTimestamp = true links = [ "https://docs.oracle.com/javase/8/docs/api/", "https://developer.android.com/reference/", ] // Set javadoc source to JDK 8 to avoid unnamed module problem // when running aggregateJavadoc with OpenJDK 13+. source("8") header = headerHtml footer = headerHtml // bottom = "" version = thisVersion } } } } task aggregateJsondocs(type: Copy) { gradle.projectsEvaluated { project.subprojects.findAll { it.plugins.hasPlugin(ShadowsPlugin) }.each { subproject -> dependsOn subproject.tasks["compileJava"] from "${subproject.buildDir}/docs/json" } } into "$buildDir/docs/json" } task aggregateDocs { dependsOn ':aggregateJavadocs' dependsOn ':aggregateJsondocs' } // aggregate test results from all projects... task aggregateTestReports(type: TestReport) { def jobNumber = System.getenv('TRAVIS_JOB_NUMBER') if (jobNumber == null) { destinationDir = file("$buildDir/reports/allTests") } else { destinationDir = file("$buildDir/reports/allTests/$jobNumber") } } afterEvaluate { def aggregateTestReportsTask = rootProject.tasks['aggregateTestReports'] allprojects.each { p -> p.afterEvaluate { p.tasks.withType(Test) { t -> aggregateTestReportsTask.reportOn binResultsDir finalizedBy aggregateTestReportsTask } } } } task prefetchSdks() { AndroidSdk.ALL_SDKS.each { androidSdk -> doLast { println("Prefetching ${androidSdk.coordinates}...") // prefetch into maven local repo... def mvnCommand = "mvn -q dependency:get -DrepoUrl=http://maven.google.com \ -DgroupId=${androidSdk.groupId} -DartifactId=${androidSdk.artifactId} \ -Dversion=${androidSdk.version}" shellExec(mvnCommand) // prefetch into gradle local cache... def config = configurations.create("sdk${androidSdk.apiLevel}") dependencies.add("sdk${androidSdk.apiLevel}", androidSdk.coordinates) // causes dependencies to be resolved: config.files } } } task prefetchInstrumentedSdks() { AndroidSdk.ALL_SDKS.each { androidSdk -> doLast { println("Prefetching ${androidSdk.preinstrumentedCoordinates}...") // prefetch into maven local repo... def mvnCommand = "mvn -q dependency:get -DrepoUrl=http://maven.google.com \ -DgroupId=${androidSdk.groupId} -DartifactId=${androidSdk.preinstrumentedArtifactId} \ -Dversion=${androidSdk.preinstrumentedVersion}" shellExec(mvnCommand) // prefetch into gradle local cache... def config = configurations.create("sdk${androidSdk.apiLevel}") dependencies.add("sdk${androidSdk.apiLevel}", androidSdk.preinstrumentedCoordinates) // causes dependencies to be resolved: config.files } } } private void shellExec(String mvnCommand) { def process = mvnCommand.execute() def out = new StringBuffer() def err = new StringBuffer() process.consumeProcessOutput(out, err) process.waitFor() if (out.size() > 0) println out if (err.size() > 0) println err if (process.exitValue() != 0) System.exit(1) } task prefetchDependencies() { doLast { allprojects.each { p -> p.configurations.each { config -> // causes dependencies to be resolved: if (config.isCanBeResolved()) { try { config.files } catch (ResolveException e) { // ignore resolution issues for integration tests and test app, sigh if (!p.path.startsWith(":integration_tests:") && !p.path.startsWith(":testapp")) { throw e } } } } } } } // for use of external initialization scripts... project.ext.allSdks = AndroidSdk.ALL_SDKS