xref: /aosp_15_r20/external/grpc-grpc-java/build.gradle (revision e07d83d3ffcef9ecfc9f7f475418ec639ff0e5fe)
1*e07d83d3SAndroid Build Coastguard Workerplugins {
2*e07d83d3SAndroid Build Coastguard Worker    id 'java' // changes the behavior of TARGET_JVM_VERSION_ATTRIBUTE
3*e07d83d3SAndroid Build Coastguard Worker
4*e07d83d3SAndroid Build Coastguard Worker    id "com.google.osdetector" apply false
5*e07d83d3SAndroid Build Coastguard Worker    id "me.champeau.gradle.japicmp" apply false
6*e07d83d3SAndroid Build Coastguard Worker    id "net.ltgt.errorprone" apply false
7*e07d83d3SAndroid Build Coastguard Worker    id 'com.google.cloud.tools.jib' apply false
8*e07d83d3SAndroid Build Coastguard Worker}
9*e07d83d3SAndroid Build Coastguard Worker
10*e07d83d3SAndroid Build Coastguard Workerimport net.ltgt.gradle.errorprone.CheckSeverity
11*e07d83d3SAndroid Build Coastguard Workerimport org.gradle.util.GUtil
12*e07d83d3SAndroid Build Coastguard Worker
13*e07d83d3SAndroid Build Coastguard Workersubprojects {
14*e07d83d3SAndroid Build Coastguard Worker    apply plugin: "checkstyle"
15*e07d83d3SAndroid Build Coastguard Worker    apply plugin: "idea"
16*e07d83d3SAndroid Build Coastguard Worker    apply plugin: "signing"
17*e07d83d3SAndroid Build Coastguard Worker    apply plugin: "jacoco"
18*e07d83d3SAndroid Build Coastguard Worker
19*e07d83d3SAndroid Build Coastguard Worker    apply plugin: "com.google.osdetector"
20*e07d83d3SAndroid Build Coastguard Worker    apply plugin: "net.ltgt.errorprone"
21*e07d83d3SAndroid Build Coastguard Worker
22*e07d83d3SAndroid Build Coastguard Worker    group = "io.grpc"
23*e07d83d3SAndroid Build Coastguard Worker    version = "1.56.1-SNAPSHOT" // CURRENT_GRPC_VERSION
24*e07d83d3SAndroid Build Coastguard Worker
25*e07d83d3SAndroid Build Coastguard Worker    repositories {
26*e07d83d3SAndroid Build Coastguard Worker        maven { // The google mirror is less flaky than mavenCentral()
27*e07d83d3SAndroid Build Coastguard Worker            url "https://maven-central.storage-download.googleapis.com/maven2/" }
28*e07d83d3SAndroid Build Coastguard Worker        mavenCentral()
29*e07d83d3SAndroid Build Coastguard Worker        mavenLocal()
30*e07d83d3SAndroid Build Coastguard Worker    }
31*e07d83d3SAndroid Build Coastguard Worker
32*e07d83d3SAndroid Build Coastguard Worker    tasks.withType(JavaCompile).configureEach {
33*e07d83d3SAndroid Build Coastguard Worker        it.options.compilerArgs += [
34*e07d83d3SAndroid Build Coastguard Worker            "-Xlint:all",
35*e07d83d3SAndroid Build Coastguard Worker            "-Xlint:-options",
36*e07d83d3SAndroid Build Coastguard Worker            "-Xlint:-path",
37*e07d83d3SAndroid Build Coastguard Worker            "-Xlint:-try"
38*e07d83d3SAndroid Build Coastguard Worker        ]
39*e07d83d3SAndroid Build Coastguard Worker        it.options.encoding = "UTF-8"
40*e07d83d3SAndroid Build Coastguard Worker        if (rootProject.hasProperty('failOnWarnings') && rootProject.failOnWarnings.toBoolean()) {
41*e07d83d3SAndroid Build Coastguard Worker            it.options.compilerArgs += ["-Werror"]
42*e07d83d3SAndroid Build Coastguard Worker        }
43*e07d83d3SAndroid Build Coastguard Worker    }
44*e07d83d3SAndroid Build Coastguard Worker
45*e07d83d3SAndroid Build Coastguard Worker    tasks.withType(GenerateModuleMetadata).configureEach {
46*e07d83d3SAndroid Build Coastguard Worker        // Module metadata, introduced in Gradle 6.0, conflicts with our publishing task for
47*e07d83d3SAndroid Build Coastguard Worker        // grpc-alts and grpc-compiler.
48*e07d83d3SAndroid Build Coastguard Worker        enabled = false
49*e07d83d3SAndroid Build Coastguard Worker    }
50*e07d83d3SAndroid Build Coastguard Worker
51*e07d83d3SAndroid Build Coastguard Worker    def isAndroid = project.name in [
52*e07d83d3SAndroid Build Coastguard Worker            'grpc-android', 'grpc-android-interop-testing', 'grpc-cronet']
53*e07d83d3SAndroid Build Coastguard Worker
54*e07d83d3SAndroid Build Coastguard Worker    ext {
55*e07d83d3SAndroid Build Coastguard Worker        def exeSuffix = osdetector.os == 'windows' ? ".exe" : ""
56*e07d83d3SAndroid Build Coastguard Worker        protocPluginBaseName = 'protoc-gen-grpc-java'
57*e07d83d3SAndroid Build Coastguard Worker        javaPluginPath = "$rootDir/compiler/build/exe/java_plugin/$protocPluginBaseName$exeSuffix"
58*e07d83d3SAndroid Build Coastguard Worker
59*e07d83d3SAndroid Build Coastguard Worker        configureProtoCompilation = {
60*e07d83d3SAndroid Build Coastguard Worker            String generatedSourcePath = "${projectDir}/src/generated"
61*e07d83d3SAndroid Build Coastguard Worker            project.protobuf {
62*e07d83d3SAndroid Build Coastguard Worker                protoc {
63*e07d83d3SAndroid Build Coastguard Worker                    if (project.hasProperty('protoc')) {
64*e07d83d3SAndroid Build Coastguard Worker                        path = project.protoc
65*e07d83d3SAndroid Build Coastguard Worker                    } else {
66*e07d83d3SAndroid Build Coastguard Worker                        artifact = libs.protobuf.protoc.get()
67*e07d83d3SAndroid Build Coastguard Worker                    }
68*e07d83d3SAndroid Build Coastguard Worker                }
69*e07d83d3SAndroid Build Coastguard Worker                generateProtoTasks {
70*e07d83d3SAndroid Build Coastguard Worker                    all().each { task ->
71*e07d83d3SAndroid Build Coastguard Worker                        // Recompile protos when build.gradle has been changed, because
72*e07d83d3SAndroid Build Coastguard Worker                        // it's possible the version of protoc has been changed.
73*e07d83d3SAndroid Build Coastguard Worker                        task.inputs.file("${rootProject.projectDir}/build.gradle")
74*e07d83d3SAndroid Build Coastguard Worker                          .withPathSensitivity(PathSensitivity.RELATIVE)
75*e07d83d3SAndroid Build Coastguard Worker                          .withPropertyName('root build.gradle')
76*e07d83d3SAndroid Build Coastguard Worker                        if (isAndroid) {
77*e07d83d3SAndroid Build Coastguard Worker                            task.builtins {
78*e07d83d3SAndroid Build Coastguard Worker                                java { option 'lite' }
79*e07d83d3SAndroid Build Coastguard Worker                            }
80*e07d83d3SAndroid Build Coastguard Worker                        }
81*e07d83d3SAndroid Build Coastguard Worker                    }
82*e07d83d3SAndroid Build Coastguard Worker                }
83*e07d83d3SAndroid Build Coastguard Worker            }
84*e07d83d3SAndroid Build Coastguard Worker            if (rootProject.childProjects.containsKey('grpc-compiler')) {
85*e07d83d3SAndroid Build Coastguard Worker                // Only when the codegen is built along with the project, will we be able to run
86*e07d83d3SAndroid Build Coastguard Worker                // the grpc code generator.
87*e07d83d3SAndroid Build Coastguard Worker                def syncGeneratedSources = tasks.register("syncGeneratedSources") { }
88*e07d83d3SAndroid Build Coastguard Worker                project.protobuf {
89*e07d83d3SAndroid Build Coastguard Worker                    plugins { grpc { path = javaPluginPath } }
90*e07d83d3SAndroid Build Coastguard Worker                    generateProtoTasks {
91*e07d83d3SAndroid Build Coastguard Worker                        all().each { task ->
92*e07d83d3SAndroid Build Coastguard Worker                            String variantOrSourceSet = isAndroid ? task.variant.name : task.sourceSet.name
93*e07d83d3SAndroid Build Coastguard Worker                            def syncTask = project.tasks.register("syncGeneratedSources${variantOrSourceSet}", Sync) {
94*e07d83d3SAndroid Build Coastguard Worker                                from task
95*e07d83d3SAndroid Build Coastguard Worker                                into "$generatedSourcePath/$variantOrSourceSet"
96*e07d83d3SAndroid Build Coastguard Worker                                include "grpc/"
97*e07d83d3SAndroid Build Coastguard Worker                            }
98*e07d83d3SAndroid Build Coastguard Worker                            syncGeneratedSources.configure {
99*e07d83d3SAndroid Build Coastguard Worker                                dependsOn syncTask
100*e07d83d3SAndroid Build Coastguard Worker                            }
101*e07d83d3SAndroid Build Coastguard Worker
102*e07d83d3SAndroid Build Coastguard Worker                            task.configure {
103*e07d83d3SAndroid Build Coastguard Worker                                dependsOn ':grpc-compiler:java_pluginExecutable'
104*e07d83d3SAndroid Build Coastguard Worker                                // Recompile protos when the codegen has been changed
105*e07d83d3SAndroid Build Coastguard Worker                                inputs.file javaPluginPath
106*e07d83d3SAndroid Build Coastguard Worker                                plugins { grpc { option 'noversion' } }
107*e07d83d3SAndroid Build Coastguard Worker                                if (isAndroid) {
108*e07d83d3SAndroid Build Coastguard Worker                                    plugins {
109*e07d83d3SAndroid Build Coastguard Worker                                        grpc {
110*e07d83d3SAndroid Build Coastguard Worker                                            option 'lite'
111*e07d83d3SAndroid Build Coastguard Worker                                        }
112*e07d83d3SAndroid Build Coastguard Worker                                    }
113*e07d83d3SAndroid Build Coastguard Worker                                }
114*e07d83d3SAndroid Build Coastguard Worker                            }
115*e07d83d3SAndroid Build Coastguard Worker                        }
116*e07d83d3SAndroid Build Coastguard Worker                    }
117*e07d83d3SAndroid Build Coastguard Worker                }
118*e07d83d3SAndroid Build Coastguard Worker                // Re-sync as part of a normal build, to avoid forgetting to run the sync
119*e07d83d3SAndroid Build Coastguard Worker                tasks.named("assemble").configure {
120*e07d83d3SAndroid Build Coastguard Worker                    dependsOn syncGeneratedSources
121*e07d83d3SAndroid Build Coastguard Worker                }
122*e07d83d3SAndroid Build Coastguard Worker            } else {
123*e07d83d3SAndroid Build Coastguard Worker                // Otherwise, we just use the checked-in generated code.
124*e07d83d3SAndroid Build Coastguard Worker                if (isAndroid) {
125*e07d83d3SAndroid Build Coastguard Worker                    project.android.sourceSets {
126*e07d83d3SAndroid Build Coastguard Worker                        debug { java { srcDir "${generatedSourcePath}/debug/grpc" } }
127*e07d83d3SAndroid Build Coastguard Worker                        release { java { srcDir "${generatedSourcePath}/release/grpc" } }
128*e07d83d3SAndroid Build Coastguard Worker                    }
129*e07d83d3SAndroid Build Coastguard Worker                } else {
130*e07d83d3SAndroid Build Coastguard Worker                    project.sourceSets.each() { sourceSet ->
131*e07d83d3SAndroid Build Coastguard Worker                        sourceSet.java { srcDir "${generatedSourcePath}/${sourceSet.name}/grpc" }
132*e07d83d3SAndroid Build Coastguard Worker                    }
133*e07d83d3SAndroid Build Coastguard Worker                }
134*e07d83d3SAndroid Build Coastguard Worker            }
135*e07d83d3SAndroid Build Coastguard Worker
136*e07d83d3SAndroid Build Coastguard Worker            tasks.withType(JavaCompile).configureEach {
137*e07d83d3SAndroid Build Coastguard Worker                appendToProperty(
138*e07d83d3SAndroid Build Coastguard Worker                    it.options.errorprone.excludedPaths,
139*e07d83d3SAndroid Build Coastguard Worker                    ".*/src/generated/[^/]+/java/.*" +
140*e07d83d3SAndroid Build Coastguard Worker                        "|.*/build/generated/source/proto/[^/]+/java/.*",
141*e07d83d3SAndroid Build Coastguard Worker                    "|")
142*e07d83d3SAndroid Build Coastguard Worker            }
143*e07d83d3SAndroid Build Coastguard Worker        }
144*e07d83d3SAndroid Build Coastguard Worker
145*e07d83d3SAndroid Build Coastguard Worker        libraries = libs
146*e07d83d3SAndroid Build Coastguard Worker
147*e07d83d3SAndroid Build Coastguard Worker        appendToProperty = { Property<String> property, String value, String separator ->
148*e07d83d3SAndroid Build Coastguard Worker            if (property.present) {
149*e07d83d3SAndroid Build Coastguard Worker                property.set(property.get() + separator + value)
150*e07d83d3SAndroid Build Coastguard Worker            } else {
151*e07d83d3SAndroid Build Coastguard Worker                property.set(value)
152*e07d83d3SAndroid Build Coastguard Worker            }
153*e07d83d3SAndroid Build Coastguard Worker        }
154*e07d83d3SAndroid Build Coastguard Worker    }
155*e07d83d3SAndroid Build Coastguard Worker
156*e07d83d3SAndroid Build Coastguard Worker    // Disable JavaDoc doclint on Java 8. It's annoying.
157*e07d83d3SAndroid Build Coastguard Worker    if (JavaVersion.current().isJava8Compatible()) {
158*e07d83d3SAndroid Build Coastguard Worker        allprojects {
159*e07d83d3SAndroid Build Coastguard Worker            tasks.withType(Javadoc).configureEach {
160*e07d83d3SAndroid Build Coastguard Worker                options.addStringOption('Xdoclint:none', '-quiet')
161*e07d83d3SAndroid Build Coastguard Worker            }
162*e07d83d3SAndroid Build Coastguard Worker        }
163*e07d83d3SAndroid Build Coastguard Worker    }
164*e07d83d3SAndroid Build Coastguard Worker
165*e07d83d3SAndroid Build Coastguard Worker    checkstyle {
166*e07d83d3SAndroid Build Coastguard Worker        configDirectory = file("$rootDir/buildscripts")
167*e07d83d3SAndroid Build Coastguard Worker        toolVersion = libs.checkstyle.get().version
168*e07d83d3SAndroid Build Coastguard Worker        ignoreFailures = false
169*e07d83d3SAndroid Build Coastguard Worker        if (rootProject.hasProperty("checkstyle.ignoreFailures")) {
170*e07d83d3SAndroid Build Coastguard Worker            ignoreFailures = rootProject.properties["checkstyle.ignoreFailures"].toBoolean()
171*e07d83d3SAndroid Build Coastguard Worker        }
172*e07d83d3SAndroid Build Coastguard Worker    }
173*e07d83d3SAndroid Build Coastguard Worker
174*e07d83d3SAndroid Build Coastguard Worker    if (!project.hasProperty('errorProne') || errorProne.toBoolean()) {
175*e07d83d3SAndroid Build Coastguard Worker        dependencies {
176*e07d83d3SAndroid Build Coastguard Worker            errorprone JavaVersion.current().isJava11Compatible() ? libs.errorprone.core : libs.errorprone.corejava8
177*e07d83d3SAndroid Build Coastguard Worker        }
178*e07d83d3SAndroid Build Coastguard Worker    } else {
179*e07d83d3SAndroid Build Coastguard Worker        // Disable Error Prone
180*e07d83d3SAndroid Build Coastguard Worker        tasks.withType(JavaCompile).configureEach {
181*e07d83d3SAndroid Build Coastguard Worker            options.errorprone.enabled = false
182*e07d83d3SAndroid Build Coastguard Worker        }
183*e07d83d3SAndroid Build Coastguard Worker    }
184*e07d83d3SAndroid Build Coastguard Worker
185*e07d83d3SAndroid Build Coastguard Worker    plugins.withId("java") {
186*e07d83d3SAndroid Build Coastguard Worker        sourceCompatibility = 1.8
187*e07d83d3SAndroid Build Coastguard Worker        targetCompatibility = 1.8
188*e07d83d3SAndroid Build Coastguard Worker
189*e07d83d3SAndroid Build Coastguard Worker        dependencies {
190*e07d83d3SAndroid Build Coastguard Worker            testImplementation libraries.junit,
191*e07d83d3SAndroid Build Coastguard Worker                    libraries.mockito.core,
192*e07d83d3SAndroid Build Coastguard Worker                    libraries.truth
193*e07d83d3SAndroid Build Coastguard Worker        }
194*e07d83d3SAndroid Build Coastguard Worker
195*e07d83d3SAndroid Build Coastguard Worker        tasks.named("compileTestJava").configure {
196*e07d83d3SAndroid Build Coastguard Worker            // serialVersionUID is basically guaranteed to be useless in our tests
197*e07d83d3SAndroid Build Coastguard Worker            options.compilerArgs += [
198*e07d83d3SAndroid Build Coastguard Worker                "-Xlint:-serial"
199*e07d83d3SAndroid Build Coastguard Worker            ]
200*e07d83d3SAndroid Build Coastguard Worker        }
201*e07d83d3SAndroid Build Coastguard Worker
202*e07d83d3SAndroid Build Coastguard Worker        tasks.named("jar").configure {
203*e07d83d3SAndroid Build Coastguard Worker            manifest {
204*e07d83d3SAndroid Build Coastguard Worker                attributes('Implementation-Title': name,
205*e07d83d3SAndroid Build Coastguard Worker                        'Implementation-Version': project.version)
206*e07d83d3SAndroid Build Coastguard Worker            }
207*e07d83d3SAndroid Build Coastguard Worker        }
208*e07d83d3SAndroid Build Coastguard Worker
209*e07d83d3SAndroid Build Coastguard Worker        tasks.named("javadoc").configure {
210*e07d83d3SAndroid Build Coastguard Worker            options {
211*e07d83d3SAndroid Build Coastguard Worker                encoding = 'UTF-8'
212*e07d83d3SAndroid Build Coastguard Worker                use = true
213*e07d83d3SAndroid Build Coastguard Worker                links 'https://docs.oracle.com/javase/8/docs/api/'
214*e07d83d3SAndroid Build Coastguard Worker                source = "8"
215*e07d83d3SAndroid Build Coastguard Worker            }
216*e07d83d3SAndroid Build Coastguard Worker        }
217*e07d83d3SAndroid Build Coastguard Worker
218*e07d83d3SAndroid Build Coastguard Worker        tasks.named("checkstyleMain").configure {
219*e07d83d3SAndroid Build Coastguard Worker            source = fileTree(dir: "$projectDir/src/main", include: "**/*.java")
220*e07d83d3SAndroid Build Coastguard Worker        }
221*e07d83d3SAndroid Build Coastguard Worker
222*e07d83d3SAndroid Build Coastguard Worker        tasks.named("checkstyleTest").configure {
223*e07d83d3SAndroid Build Coastguard Worker            source = fileTree(dir: "$projectDir/src/test", include: "**/*.java")
224*e07d83d3SAndroid Build Coastguard Worker        }
225*e07d83d3SAndroid Build Coastguard Worker
226*e07d83d3SAndroid Build Coastguard Worker        // At a test failure, log the stack trace to the console so that we don't
227*e07d83d3SAndroid Build Coastguard Worker        // have to open the HTML in a browser.
228*e07d83d3SAndroid Build Coastguard Worker        tasks.named("test").configure {
229*e07d83d3SAndroid Build Coastguard Worker            testLogging {
230*e07d83d3SAndroid Build Coastguard Worker                exceptionFormat = 'full'
231*e07d83d3SAndroid Build Coastguard Worker                showExceptions true
232*e07d83d3SAndroid Build Coastguard Worker                showCauses true
233*e07d83d3SAndroid Build Coastguard Worker                showStackTraces true
234*e07d83d3SAndroid Build Coastguard Worker            }
235*e07d83d3SAndroid Build Coastguard Worker            maxHeapSize = '1500m'
236*e07d83d3SAndroid Build Coastguard Worker        }
237*e07d83d3SAndroid Build Coastguard Worker
238*e07d83d3SAndroid Build Coastguard Worker        if (!project.hasProperty('errorProne') || errorProne.toBoolean()) {
239*e07d83d3SAndroid Build Coastguard Worker            dependencies {
240*e07d83d3SAndroid Build Coastguard Worker                annotationProcessor libs.guava.betaChecker
241*e07d83d3SAndroid Build Coastguard Worker            }
242*e07d83d3SAndroid Build Coastguard Worker        }
243*e07d83d3SAndroid Build Coastguard Worker
244*e07d83d3SAndroid Build Coastguard Worker        tasks.named("compileJava").configure {
245*e07d83d3SAndroid Build Coastguard Worker            // This project targets Java 7 (no time.Duration class)
246*e07d83d3SAndroid Build Coastguard Worker            options.errorprone.check("PreferJavaTimeOverload", CheckSeverity.OFF)
247*e07d83d3SAndroid Build Coastguard Worker            options.errorprone.check("JavaUtilDate", CheckSeverity.OFF)
248*e07d83d3SAndroid Build Coastguard Worker            // The warning fails to provide a source location
249*e07d83d3SAndroid Build Coastguard Worker            options.errorprone.check("MissingSummary", CheckSeverity.OFF)
250*e07d83d3SAndroid Build Coastguard Worker        }
251*e07d83d3SAndroid Build Coastguard Worker        tasks.named("compileTestJava").configure {
252*e07d83d3SAndroid Build Coastguard Worker            // LinkedList doesn't hurt much in tests and has lots of usages
253*e07d83d3SAndroid Build Coastguard Worker            options.errorprone.check("JdkObsolete", CheckSeverity.OFF)
254*e07d83d3SAndroid Build Coastguard Worker            options.errorprone.check("PreferJavaTimeOverload", CheckSeverity.OFF)
255*e07d83d3SAndroid Build Coastguard Worker            options.errorprone.check("JavaUtilDate", CheckSeverity.OFF)
256*e07d83d3SAndroid Build Coastguard Worker        }
257*e07d83d3SAndroid Build Coastguard Worker
258*e07d83d3SAndroid Build Coastguard Worker        plugins.withId("ru.vyarus.animalsniffer") {
259*e07d83d3SAndroid Build Coastguard Worker	    // Only available after java plugin has loaded
260*e07d83d3SAndroid Build Coastguard Worker            animalsniffer {
261*e07d83d3SAndroid Build Coastguard Worker                toolVersion = libs.animalsniffer.asProvider().get().version
262*e07d83d3SAndroid Build Coastguard Worker            }
263*e07d83d3SAndroid Build Coastguard Worker        }
264*e07d83d3SAndroid Build Coastguard Worker    }
265*e07d83d3SAndroid Build Coastguard Worker
266*e07d83d3SAndroid Build Coastguard Worker    plugins.withId("java-library") {
267*e07d83d3SAndroid Build Coastguard Worker        // Detect Maven Enforcer's dependencyConvergence failures. We only care
268*e07d83d3SAndroid Build Coastguard Worker        // for artifacts used as libraries by others with Maven.
269*e07d83d3SAndroid Build Coastguard Worker        tasks.register('checkUpperBoundDeps') {
270*e07d83d3SAndroid Build Coastguard Worker            inputs.files(configurations.runtimeClasspath).withNormalizer(ClasspathNormalizer)
271*e07d83d3SAndroid Build Coastguard Worker            outputs.file("${buildDir}/tmp/${name}") // Fake output for UP-TO-DATE checking
272*e07d83d3SAndroid Build Coastguard Worker            doLast {
273*e07d83d3SAndroid Build Coastguard Worker                requireUpperBoundDepsMatch(configurations.runtimeClasspath, project)
274*e07d83d3SAndroid Build Coastguard Worker            }
275*e07d83d3SAndroid Build Coastguard Worker        }
276*e07d83d3SAndroid Build Coastguard Worker        tasks.named('compileJava').configure {
277*e07d83d3SAndroid Build Coastguard Worker            dependsOn checkUpperBoundDeps
278*e07d83d3SAndroid Build Coastguard Worker        }
279*e07d83d3SAndroid Build Coastguard Worker    }
280*e07d83d3SAndroid Build Coastguard Worker
281*e07d83d3SAndroid Build Coastguard Worker    plugins.withId("me.champeau.jmh") {
282*e07d83d3SAndroid Build Coastguard Worker        // invoke jmh on a single benchmark class like so:
283*e07d83d3SAndroid Build Coastguard Worker        //   ./gradlew -PjmhIncludeSingleClass=StatsTraceContextBenchmark clean :grpc-core:jmh
284*e07d83d3SAndroid Build Coastguard Worker	tasks.named("compileJmhJava").configure {
285*e07d83d3SAndroid Build Coastguard Worker	    sourceCompatibility = 1.8
286*e07d83d3SAndroid Build Coastguard Worker	    targetCompatibility = 1.8
287*e07d83d3SAndroid Build Coastguard Worker	}
288*e07d83d3SAndroid Build Coastguard Worker        tasks.named("jmh").configure {
289*e07d83d3SAndroid Build Coastguard Worker            warmupIterations = 10
290*e07d83d3SAndroid Build Coastguard Worker            iterations = 10
291*e07d83d3SAndroid Build Coastguard Worker            fork = 1
292*e07d83d3SAndroid Build Coastguard Worker            // None of our benchmarks need the tests, and we have pseudo-circular
293*e07d83d3SAndroid Build Coastguard Worker            // dependencies that break when including them. (context's testCompile
294*e07d83d3SAndroid Build Coastguard Worker            // depends on core; core's testCompile depends on testing)
295*e07d83d3SAndroid Build Coastguard Worker            includeTests = false
296*e07d83d3SAndroid Build Coastguard Worker            if (project.hasProperty('jmhIncludeSingleClass')) {
297*e07d83d3SAndroid Build Coastguard Worker                includes = [
298*e07d83d3SAndroid Build Coastguard Worker                    project.property('jmhIncludeSingleClass')
299*e07d83d3SAndroid Build Coastguard Worker                ]
300*e07d83d3SAndroid Build Coastguard Worker            }
301*e07d83d3SAndroid Build Coastguard Worker        }
302*e07d83d3SAndroid Build Coastguard Worker    }
303*e07d83d3SAndroid Build Coastguard Worker
304*e07d83d3SAndroid Build Coastguard Worker    plugins.withId("com.github.johnrengelman.shadow") {
305*e07d83d3SAndroid Build Coastguard Worker        tasks.named("shadowJar").configure {
306*e07d83d3SAndroid Build Coastguard Worker            // Do a dance to remove Class-Path. This needs to run after the doFirst() from the
307*e07d83d3SAndroid Build Coastguard Worker            // shadow plugin that adds Class-Path and before the core jar action. Using doFirst will
308*e07d83d3SAndroid Build Coastguard Worker            // have this run before the shadow plugin, and doLast will run after the core jar
309*e07d83d3SAndroid Build Coastguard Worker            // action. See #8606.
310*e07d83d3SAndroid Build Coastguard Worker            // The shadow plugin adds another doFirst when application is used for setting
311*e07d83d3SAndroid Build Coastguard Worker            // Main-Class. Ordering with it doesn't matter.
312*e07d83d3SAndroid Build Coastguard Worker            actions.add(plugins.hasPlugin("application") ? 2 : 1, new Action<Task>() {
313*e07d83d3SAndroid Build Coastguard Worker                @Override public void execute(Task task) {
314*e07d83d3SAndroid Build Coastguard Worker                    if (!task.manifest.attributes.remove("Class-Path")) {
315*e07d83d3SAndroid Build Coastguard Worker                        throw new AssertionError("Did not find Class-Path to remove from manifest")
316*e07d83d3SAndroid Build Coastguard Worker                    }
317*e07d83d3SAndroid Build Coastguard Worker                }
318*e07d83d3SAndroid Build Coastguard Worker            })
319*e07d83d3SAndroid Build Coastguard Worker        }
320*e07d83d3SAndroid Build Coastguard Worker    }
321*e07d83d3SAndroid Build Coastguard Worker
322*e07d83d3SAndroid Build Coastguard Worker    plugins.withId("maven-publish") {
323*e07d83d3SAndroid Build Coastguard Worker        publishing {
324*e07d83d3SAndroid Build Coastguard Worker            publications {
325*e07d83d3SAndroid Build Coastguard Worker                // do not use mavenJava, as java plugin will modify it via "magic"
326*e07d83d3SAndroid Build Coastguard Worker                maven(MavenPublication) {
327*e07d83d3SAndroid Build Coastguard Worker                    pom {
328*e07d83d3SAndroid Build Coastguard Worker                        name = project.group + ":" + project.name
329*e07d83d3SAndroid Build Coastguard Worker                        url = 'https://github.com/grpc/grpc-java'
330*e07d83d3SAndroid Build Coastguard Worker                        afterEvaluate {
331*e07d83d3SAndroid Build Coastguard Worker                            // description is not available until evaluated.
332*e07d83d3SAndroid Build Coastguard Worker                            description = project.description
333*e07d83d3SAndroid Build Coastguard Worker                        }
334*e07d83d3SAndroid Build Coastguard Worker
335*e07d83d3SAndroid Build Coastguard Worker                        scm {
336*e07d83d3SAndroid Build Coastguard Worker                            connection = 'scm:git:https://github.com/grpc/grpc-java.git'
337*e07d83d3SAndroid Build Coastguard Worker                            developerConnection = 'scm:git:[email protected]:grpc/grpc-java.git'
338*e07d83d3SAndroid Build Coastguard Worker                            url = 'https://github.com/grpc/grpc-java'
339*e07d83d3SAndroid Build Coastguard Worker                        }
340*e07d83d3SAndroid Build Coastguard Worker
341*e07d83d3SAndroid Build Coastguard Worker                        licenses {
342*e07d83d3SAndroid Build Coastguard Worker                            license {
343*e07d83d3SAndroid Build Coastguard Worker                                name = 'Apache 2.0'
344*e07d83d3SAndroid Build Coastguard Worker                                url = 'https://opensource.org/licenses/Apache-2.0'
345*e07d83d3SAndroid Build Coastguard Worker                            }
346*e07d83d3SAndroid Build Coastguard Worker                        }
347*e07d83d3SAndroid Build Coastguard Worker
348*e07d83d3SAndroid Build Coastguard Worker                        developers {
349*e07d83d3SAndroid Build Coastguard Worker                            developer {
350*e07d83d3SAndroid Build Coastguard Worker                                id = "grpc.io"
351*e07d83d3SAndroid Build Coastguard Worker                                name = "gRPC Contributors"
352*e07d83d3SAndroid Build Coastguard Worker                                email = "[email protected]"
353*e07d83d3SAndroid Build Coastguard Worker                                url = "https://grpc.io/"
354*e07d83d3SAndroid Build Coastguard Worker                                organization = "gRPC Authors"
355*e07d83d3SAndroid Build Coastguard Worker                                organizationUrl = "https://www.google.com"
356*e07d83d3SAndroid Build Coastguard Worker                            }
357*e07d83d3SAndroid Build Coastguard Worker                        }
358*e07d83d3SAndroid Build Coastguard Worker                    }
359*e07d83d3SAndroid Build Coastguard Worker                }
360*e07d83d3SAndroid Build Coastguard Worker            }
361*e07d83d3SAndroid Build Coastguard Worker            repositories {
362*e07d83d3SAndroid Build Coastguard Worker                maven {
363*e07d83d3SAndroid Build Coastguard Worker                    if (rootProject.hasProperty('repositoryDir')) {
364*e07d83d3SAndroid Build Coastguard Worker                        url = new File(rootProject.repositoryDir).toURI()
365*e07d83d3SAndroid Build Coastguard Worker                    } else {
366*e07d83d3SAndroid Build Coastguard Worker                        String stagingUrl
367*e07d83d3SAndroid Build Coastguard Worker                        if (rootProject.hasProperty('repositoryId')) {
368*e07d83d3SAndroid Build Coastguard Worker                            stagingUrl = 'https://oss.sonatype.org/service/local/staging/deployByRepositoryId/' +
369*e07d83d3SAndroid Build Coastguard Worker                                    rootProject.repositoryId
370*e07d83d3SAndroid Build Coastguard Worker                        } else {
371*e07d83d3SAndroid Build Coastguard Worker                            stagingUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
372*e07d83d3SAndroid Build Coastguard Worker                        }
373*e07d83d3SAndroid Build Coastguard Worker                        credentials {
374*e07d83d3SAndroid Build Coastguard Worker                            if (rootProject.hasProperty('ossrhUsername') && rootProject.hasProperty('ossrhPassword')) {
375*e07d83d3SAndroid Build Coastguard Worker                                username = rootProject.ossrhUsername
376*e07d83d3SAndroid Build Coastguard Worker                                password = rootProject.ossrhPassword
377*e07d83d3SAndroid Build Coastguard Worker                            }
378*e07d83d3SAndroid Build Coastguard Worker                        }
379*e07d83d3SAndroid Build Coastguard Worker                        def releaseUrl = stagingUrl
380*e07d83d3SAndroid Build Coastguard Worker                        def snapshotUrl = 'https://oss.sonatype.org/content/repositories/snapshots/'
381*e07d83d3SAndroid Build Coastguard Worker                        url = version.endsWith('SNAPSHOT') ? snapshotUrl : releaseUrl
382*e07d83d3SAndroid Build Coastguard Worker                    }
383*e07d83d3SAndroid Build Coastguard Worker                }
384*e07d83d3SAndroid Build Coastguard Worker            }
385*e07d83d3SAndroid Build Coastguard Worker        }
386*e07d83d3SAndroid Build Coastguard Worker
387*e07d83d3SAndroid Build Coastguard Worker        signing {
388*e07d83d3SAndroid Build Coastguard Worker            required false
389*e07d83d3SAndroid Build Coastguard Worker            sign publishing.publications.maven
390*e07d83d3SAndroid Build Coastguard Worker        }
391*e07d83d3SAndroid Build Coastguard Worker
392*e07d83d3SAndroid Build Coastguard Worker        plugins.withId("java") {
393*e07d83d3SAndroid Build Coastguard Worker            java {
394*e07d83d3SAndroid Build Coastguard Worker                withJavadocJar()
395*e07d83d3SAndroid Build Coastguard Worker                withSourcesJar()
396*e07d83d3SAndroid Build Coastguard Worker            }
397*e07d83d3SAndroid Build Coastguard Worker
398*e07d83d3SAndroid Build Coastguard Worker            publishing {
399*e07d83d3SAndroid Build Coastguard Worker                publications {
400*e07d83d3SAndroid Build Coastguard Worker                    maven {
401*e07d83d3SAndroid Build Coastguard Worker                        if (project.name != 'grpc-netty-shaded') {
402*e07d83d3SAndroid Build Coastguard Worker                            from components.java
403*e07d83d3SAndroid Build Coastguard Worker                        }
404*e07d83d3SAndroid Build Coastguard Worker                    }
405*e07d83d3SAndroid Build Coastguard Worker                }
406*e07d83d3SAndroid Build Coastguard Worker            }
407*e07d83d3SAndroid Build Coastguard Worker        }
408*e07d83d3SAndroid Build Coastguard Worker    }
409*e07d83d3SAndroid Build Coastguard Worker
410*e07d83d3SAndroid Build Coastguard Worker    // Run with: ./gradlew japicmp --continue
411*e07d83d3SAndroid Build Coastguard Worker    plugins.withId("me.champeau.gradle.japicmp") {
412*e07d83d3SAndroid Build Coastguard Worker        def baselineGrpcVersion = '1.6.1'
413*e07d83d3SAndroid Build Coastguard Worker
414*e07d83d3SAndroid Build Coastguard Worker        // Get the baseline version's jar for this subproject
415*e07d83d3SAndroid Build Coastguard Worker        File baselineArtifact = null
416*e07d83d3SAndroid Build Coastguard Worker        // Use a detached configuration, otherwise the current version's jar will take precedence
417*e07d83d3SAndroid Build Coastguard Worker        // over the baseline jar.
418*e07d83d3SAndroid Build Coastguard Worker        // A necessary hack, the intuitive thing does NOT work:
419*e07d83d3SAndroid Build Coastguard Worker        // https://discuss.gradle.org/t/is-the-default-configuration-leaking-into-independent-configurations/2088/6
420*e07d83d3SAndroid Build Coastguard Worker        def oldGroup = project.group
421*e07d83d3SAndroid Build Coastguard Worker        try {
422*e07d83d3SAndroid Build Coastguard Worker            project.group = 'virtual_group_for_japicmp'
423*e07d83d3SAndroid Build Coastguard Worker            String depModule = "io.grpc:${project.name}:${baselineGrpcVersion}@jar"
424*e07d83d3SAndroid Build Coastguard Worker            String depJar = "${project.name}-${baselineGrpcVersion}.jar"
425*e07d83d3SAndroid Build Coastguard Worker            Configuration configuration = configurations.detachedConfiguration(
426*e07d83d3SAndroid Build Coastguard Worker                    dependencies.create(depModule)
427*e07d83d3SAndroid Build Coastguard Worker                    )
428*e07d83d3SAndroid Build Coastguard Worker            baselineArtifact = files(configuration.files).filter {
429*e07d83d3SAndroid Build Coastguard Worker                it.name.equals(depJar)
430*e07d83d3SAndroid Build Coastguard Worker            }.singleFile
431*e07d83d3SAndroid Build Coastguard Worker        } finally {
432*e07d83d3SAndroid Build Coastguard Worker            project.group = oldGroup
433*e07d83d3SAndroid Build Coastguard Worker        }
434*e07d83d3SAndroid Build Coastguard Worker
435*e07d83d3SAndroid Build Coastguard Worker        // Add a japicmp task that compares the current .jar with baseline .jar
436*e07d83d3SAndroid Build Coastguard Worker        tasks.register("japicmp", me.champeau.gradle.japicmp.JapicmpTask) {
437*e07d83d3SAndroid Build Coastguard Worker            dependsOn jar
438*e07d83d3SAndroid Build Coastguard Worker            oldClasspath = files(baselineArtifact)
439*e07d83d3SAndroid Build Coastguard Worker            newClasspath = files(jar.archiveFile)
440*e07d83d3SAndroid Build Coastguard Worker            onlyBinaryIncompatibleModified = false
441*e07d83d3SAndroid Build Coastguard Worker            // Be quiet about things that did not change
442*e07d83d3SAndroid Build Coastguard Worker            onlyModified = true
443*e07d83d3SAndroid Build Coastguard Worker            // This task should fail if there are incompatible changes
444*e07d83d3SAndroid Build Coastguard Worker            failOnModification = true
445*e07d83d3SAndroid Build Coastguard Worker            ignoreMissingClasses = true
446*e07d83d3SAndroid Build Coastguard Worker            htmlOutputFile = file("$buildDir/reports/japi.html")
447*e07d83d3SAndroid Build Coastguard Worker
448*e07d83d3SAndroid Build Coastguard Worker            packageExcludes = ['io.grpc.internal']
449*e07d83d3SAndroid Build Coastguard Worker
450*e07d83d3SAndroid Build Coastguard Worker            // Also break on source incompatible changes, not just binary.
451*e07d83d3SAndroid Build Coastguard Worker            // Eg adding abstract method to public class.
452*e07d83d3SAndroid Build Coastguard Worker            // TODO(zpencer): enable after japicmp-gradle-plugin/pull/14
453*e07d83d3SAndroid Build Coastguard Worker            // breakOnSourceIncompatibility = true
454*e07d83d3SAndroid Build Coastguard Worker
455*e07d83d3SAndroid Build Coastguard Worker            // Ignore any classes or methods marked @ExperimentalApi
456*e07d83d3SAndroid Build Coastguard Worker            // TODO(zpencer): enable after japicmp-gradle-plugin/pull/15
457*e07d83d3SAndroid Build Coastguard Worker            // annotationExcludes = ['@io.grpc.ExperimentalApi']
458*e07d83d3SAndroid Build Coastguard Worker        }
459*e07d83d3SAndroid Build Coastguard Worker    }
460*e07d83d3SAndroid Build Coastguard Worker}
461*e07d83d3SAndroid Build Coastguard Worker
462*e07d83d3SAndroid Build Coastguard Workerclass DepAndParents {
463*e07d83d3SAndroid Build Coastguard Worker    DependencyResult dep
464*e07d83d3SAndroid Build Coastguard Worker    List<String> parents
465*e07d83d3SAndroid Build Coastguard Worker}
466*e07d83d3SAndroid Build Coastguard Worker
467*e07d83d3SAndroid Build Coastguard Worker/**
468*e07d83d3SAndroid Build Coastguard Worker * Make sure that Maven would select the same versions as Gradle selected.
469*e07d83d3SAndroid Build Coastguard Worker * This is essentially the same as if we used Maven Enforcer's
470*e07d83d3SAndroid Build Coastguard Worker * requireUpperBoundDeps for our artifacts.
471*e07d83d3SAndroid Build Coastguard Worker */
472*e07d83d3SAndroid Build Coastguard Workerdef requireUpperBoundDepsMatch(Configuration conf, Project project) {
473*e07d83d3SAndroid Build Coastguard Worker    // artifact name => version
474*e07d83d3SAndroid Build Coastguard Worker    Map<String,String> golden = conf.resolvedConfiguration.resolvedArtifacts.collectEntries {
475*e07d83d3SAndroid Build Coastguard Worker        ResolvedArtifact it ->
476*e07d83d3SAndroid Build Coastguard Worker            ModuleVersionIdentifier id = it.moduleVersion.id
477*e07d83d3SAndroid Build Coastguard Worker            [id.group + ":" + id.name, id.version]
478*e07d83d3SAndroid Build Coastguard Worker    }
479*e07d83d3SAndroid Build Coastguard Worker    // Breadth-first search like Maven for dependency resolution
480*e07d83d3SAndroid Build Coastguard Worker    Queue<DepAndParents> queue = new ArrayDeque<>()
481*e07d83d3SAndroid Build Coastguard Worker    conf.incoming.resolutionResult.root.dependencies.each {
482*e07d83d3SAndroid Build Coastguard Worker        queue.add(new DepAndParents(dep: it, parents: [project.displayName]))
483*e07d83d3SAndroid Build Coastguard Worker    }
484*e07d83d3SAndroid Build Coastguard Worker    Set<String> found = new HashSet<>()
485*e07d83d3SAndroid Build Coastguard Worker    while (!queue.isEmpty()) {
486*e07d83d3SAndroid Build Coastguard Worker        DepAndParents depAndParents = queue.remove()
487*e07d83d3SAndroid Build Coastguard Worker        ResolvedDependencyResult result = (ResolvedDependencyResult) depAndParents.dep
488*e07d83d3SAndroid Build Coastguard Worker        ModuleVersionIdentifier id = result.selected.moduleVersion
489*e07d83d3SAndroid Build Coastguard Worker        String artifact = id.group + ":" + id.name
490*e07d83d3SAndroid Build Coastguard Worker        if (found.contains(artifact))
491*e07d83d3SAndroid Build Coastguard Worker            continue
492*e07d83d3SAndroid Build Coastguard Worker        found.add(artifact)
493*e07d83d3SAndroid Build Coastguard Worker        String version
494*e07d83d3SAndroid Build Coastguard Worker        if (result.requested instanceof ProjectComponentSelector) {
495*e07d83d3SAndroid Build Coastguard Worker            ProjectComponentSelector selector = (ProjectComponentSelector) result.requested
496*e07d83d3SAndroid Build Coastguard Worker            version = project.findProject(selector.projectPath).version
497*e07d83d3SAndroid Build Coastguard Worker        } else {
498*e07d83d3SAndroid Build Coastguard Worker            version = ((ModuleComponentSelector) result.requested).version
499*e07d83d3SAndroid Build Coastguard Worker        }
500*e07d83d3SAndroid Build Coastguard Worker        String goldenVersion = golden[artifact]
501*e07d83d3SAndroid Build Coastguard Worker        if (goldenVersion != version && "[$goldenVersion]" != version) {
502*e07d83d3SAndroid Build Coastguard Worker            throw new RuntimeException(
503*e07d83d3SAndroid Build Coastguard Worker                "Maven version skew: $artifact ($version != $goldenVersion) "
504*e07d83d3SAndroid Build Coastguard Worker                + "Bad version dependency path: " + depAndParents.parents
505*e07d83d3SAndroid Build Coastguard Worker                + " Run './gradlew $project.path:dependencies --configuration $conf.name' "
506*e07d83d3SAndroid Build Coastguard Worker                + "to diagnose")
507*e07d83d3SAndroid Build Coastguard Worker        }
508*e07d83d3SAndroid Build Coastguard Worker        result.selected.dependencies.each {
509*e07d83d3SAndroid Build Coastguard Worker            queue.add(new DepAndParents(
510*e07d83d3SAndroid Build Coastguard Worker                dep: it, parents: depAndParents.parents + [artifact + ":" + version]))
511*e07d83d3SAndroid Build Coastguard Worker        }
512*e07d83d3SAndroid Build Coastguard Worker    }
513*e07d83d3SAndroid Build Coastguard Worker}
514*e07d83d3SAndroid Build Coastguard Worker
515*e07d83d3SAndroid Build Coastguard Workerrepositories {
516*e07d83d3SAndroid Build Coastguard Worker    mavenCentral()
517*e07d83d3SAndroid Build Coastguard Worker    google()
518*e07d83d3SAndroid Build Coastguard Worker}
519*e07d83d3SAndroid Build Coastguard Worker
520*e07d83d3SAndroid Build Coastguard Workerdef isAcceptableVersion(ModuleComponentIdentifier candidate) {
521*e07d83d3SAndroid Build Coastguard Worker    String group = candidate.group
522*e07d83d3SAndroid Build Coastguard Worker    String module = candidate.module
523*e07d83d3SAndroid Build Coastguard Worker    String version = candidate.version
524*e07d83d3SAndroid Build Coastguard Worker    if (group == 'com.google.guava')
525*e07d83d3SAndroid Build Coastguard Worker        return true
526*e07d83d3SAndroid Build Coastguard Worker    if (group == 'io.netty' && version.contains('Final'))
527*e07d83d3SAndroid Build Coastguard Worker        return true
528*e07d83d3SAndroid Build Coastguard Worker    if (module == 'android-api-level-19')
529*e07d83d3SAndroid Build Coastguard Worker        return true
530*e07d83d3SAndroid Build Coastguard Worker    return version ==~ /^[0-9]+(\.[0-9]+)+$/
531*e07d83d3SAndroid Build Coastguard Worker}
532*e07d83d3SAndroid Build Coastguard Worker
533*e07d83d3SAndroid Build Coastguard Workerconfigurations {
534*e07d83d3SAndroid Build Coastguard Worker    checkForUpdates {
535*e07d83d3SAndroid Build Coastguard Worker        attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 8)
536*e07d83d3SAndroid Build Coastguard Worker        resolutionStrategy {
537*e07d83d3SAndroid Build Coastguard Worker            componentSelection {
538*e07d83d3SAndroid Build Coastguard Worker                all {
539*e07d83d3SAndroid Build Coastguard Worker                    if (!isAcceptableVersion(it.candidate))
540*e07d83d3SAndroid Build Coastguard Worker                        it.reject("Not stable version")
541*e07d83d3SAndroid Build Coastguard Worker                }
542*e07d83d3SAndroid Build Coastguard Worker            }
543*e07d83d3SAndroid Build Coastguard Worker        }
544*e07d83d3SAndroid Build Coastguard Worker    }
545*e07d83d3SAndroid Build Coastguard Worker}
546*e07d83d3SAndroid Build Coastguard Worker
547*e07d83d3SAndroid Build Coastguard Worker// Checks every dependency in the version catalog to see if there is a newer
548*e07d83d3SAndroid Build Coastguard Worker// version available. The 'checkForUpdates' configuration restricts the
549*e07d83d3SAndroid Build Coastguard Worker// versions considered.
550*e07d83d3SAndroid Build Coastguard Workertasks.register('checkForUpdates') {
551*e07d83d3SAndroid Build Coastguard Worker    doLast {
552*e07d83d3SAndroid Build Coastguard Worker        def updateConf = project.configurations.checkForUpdates
553*e07d83d3SAndroid Build Coastguard Worker        updateConf.setVisible(false)
554*e07d83d3SAndroid Build Coastguard Worker        updateConf.setTransitive(false)
555*e07d83d3SAndroid Build Coastguard Worker        def versionCatalog = project.extensions.getByType(VersionCatalogsExtension).named("libs")
556*e07d83d3SAndroid Build Coastguard Worker        versionCatalog.libraryAliases.each { name ->
557*e07d83d3SAndroid Build Coastguard Worker            def dep = versionCatalog.findLibrary(name).get().get()
558*e07d83d3SAndroid Build Coastguard Worker
559*e07d83d3SAndroid Build Coastguard Worker            def oldConf = updateConf.copy()
560*e07d83d3SAndroid Build Coastguard Worker            def oldDep = project.dependencies.create(
561*e07d83d3SAndroid Build Coastguard Worker                group: dep.group, name: dep.name, version: dep.versionConstraint, classifier: 'pom')
562*e07d83d3SAndroid Build Coastguard Worker            oldConf.dependencies.add(oldDep)
563*e07d83d3SAndroid Build Coastguard Worker            def oldResolved = oldConf.resolvedConfiguration.resolvedArtifacts.iterator().next()
564*e07d83d3SAndroid Build Coastguard Worker
565*e07d83d3SAndroid Build Coastguard Worker            def newConf = updateConf.copy()
566*e07d83d3SAndroid Build Coastguard Worker            def newDep = project.dependencies.create(
567*e07d83d3SAndroid Build Coastguard Worker                group: dep.group, name: dep.name, version: '+', classifier: 'pom')
568*e07d83d3SAndroid Build Coastguard Worker            newConf.dependencies.add(newDep)
569*e07d83d3SAndroid Build Coastguard Worker            def newResolved = newConf.resolvedConfiguration.resolvedArtifacts.iterator().next()
570*e07d83d3SAndroid Build Coastguard Worker            if (oldResolved != newResolved) {
571*e07d83d3SAndroid Build Coastguard Worker                def oldId = oldResolved.id.componentIdentifier
572*e07d83d3SAndroid Build Coastguard Worker                def newId = newResolved.id.componentIdentifier
573*e07d83d3SAndroid Build Coastguard Worker                println("${newId.group}:${newId.module} ${oldId.version} -> ${newId.version}")
574*e07d83d3SAndroid Build Coastguard Worker            }
575*e07d83d3SAndroid Build Coastguard Worker        }
576*e07d83d3SAndroid Build Coastguard Worker    }
577*e07d83d3SAndroid Build Coastguard Worker}
578