From 95eaed25f61ae0a171e2e53a98634986736c86a6 Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Tue, 18 Nov 2025 15:46:26 -0800 Subject: [PATCH 1/2] buildSrc: checkForUpdates comments to tune version search This will make it more likely that we notice minor and patch releases for dependencies that we can't update to the brand newest while also reducing the checkForUpdate noise/toil. --- build.gradle | 2 +- .../io/grpc/gradle/CheckForUpdatesTask.java | 43 +++++++++++++++++-- gradle/libs.versions.toml | 18 +++++++- 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 38ee6220169..50b7419df64 100644 --- a/build.gradle +++ b/build.gradle @@ -533,5 +533,5 @@ configurations { } } -tasks.register('checkForUpdates', CheckForUpdatesTask, project.configurations.checkForUpdates, "libs") +tasks.register('checkForUpdates', CheckForUpdatesTask, project.configurations.checkForUpdates, "libs", layout.projectDirectory.file("gradle/libs.versions.toml")) diff --git a/buildSrc/src/main/java/io/grpc/gradle/CheckForUpdatesTask.java b/buildSrc/src/main/java/io/grpc/gradle/CheckForUpdatesTask.java index 9d0156a1b72..fce76c1de53 100644 --- a/buildSrc/src/main/java/io/grpc/gradle/CheckForUpdatesTask.java +++ b/buildSrc/src/main/java/io/grpc/gradle/CheckForUpdatesTask.java @@ -16,11 +16,15 @@ package io.grpc.gradle; +import java.io.IOException; +import java.nio.file.Files; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import javax.inject.Inject; import org.gradle.api.DefaultTask; import org.gradle.api.artifacts.Configuration; @@ -32,6 +36,7 @@ import org.gradle.api.artifacts.result.ResolvedComponentResult; import org.gradle.api.artifacts.result.ResolvedDependencyResult; import org.gradle.api.artifacts.result.UnresolvedDependencyResult; +import org.gradle.api.file.RegularFile; import org.gradle.api.provider.Provider; import org.gradle.api.tasks.Input; import org.gradle.api.tasks.Nested; @@ -45,7 +50,23 @@ public abstract class CheckForUpdatesTask extends DefaultTask { private final Set libraries; @Inject - public CheckForUpdatesTask(Configuration updateConf, String catalog) { + public CheckForUpdatesTask(Configuration updateConf, String catalog, RegularFile commentFile) + throws IOException { + // Check for overrides to the default version selection ('+'), using comments of the form: + // # checkForUpdates: library-name:1.2.+ + List fileComments = Files.lines(commentFile.getAsFile().toPath()) + .filter(l -> l.matches("# *checkForUpdates:.*")) + .map(l -> l.replaceFirst("# *checkForUpdates:", "").strip()) + .collect(Collectors.toList()); + Map aliasToVersionSelector = new HashMap<>(2*fileComments.size()); + for (String comment : fileComments) { + String[] parts = comment.split(":", 2); + String name = parts[0].replaceAll("[_-]", "."); + if (aliasToVersionSelector.put(name, parts[1]) != null) { + throw new RuntimeException("Duplicate checkForUpdates comment for library: " + name); + } + } + updateConf.setVisible(false); updateConf.setTransitive(false); VersionCatalog versionCatalog = getProject().getExtensions().getByType(VersionCatalogsExtension.class).named(catalog); @@ -59,8 +80,12 @@ public CheckForUpdatesTask(Configuration updateConf, String catalog) { oldConf.getDependencies().add(oldDep); Configuration newConf = updateConf.copy(); + String versionSelector = aliasToVersionSelector.remove(name); + if (versionSelector == null) { + versionSelector = "+"; + } Dependency newDep = getProject().getDependencies().create( - depMap(dep.getGroup(), dep.getName(), "+", "pom")); + depMap(dep.getGroup(), dep.getName(), versionSelector, "pom")); newConf.getDependencies().add(newDep); libraries.add(new Library( @@ -68,6 +93,10 @@ public CheckForUpdatesTask(Configuration updateConf, String catalog) { oldConf.getIncoming().getResolutionResult().getRootComponent(), newConf.getIncoming().getResolutionResult().getRootComponent())); } + if (!aliasToVersionSelector.isEmpty()) { + throw new RuntimeException( + "Unused checkForUpdates comments: " + aliasToVersionSelector.keySet()); + } this.libraries = Collections.unmodifiableSet(libraries); } @@ -96,10 +125,16 @@ public void checkForUpdates() { "- Current version of libs.%s not resolved", name)); continue; } + DependencyResult newResult = lib.getNewResult().get().getDependencies().iterator().next(); + if (newResult instanceof UnresolvedDependencyResult) { + System.out.println(String.format( + "- New version of libs.%s not resolved", name)); + continue; + } ModuleVersionIdentifier oldId = ((ResolvedDependencyResult) oldResult).getSelected().getModuleVersion(); - ModuleVersionIdentifier newId = ((ResolvedDependencyResult) lib.getNewResult().get() - .getDependencies().iterator().next()).getSelected().getModuleVersion(); + ModuleVersionIdentifier newId = + ((ResolvedDependencyResult) newResult).getSelected().getModuleVersion(); if (oldId != newId) { System.out.println(String.format( "libs.%s = %s %s -> %s", diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3d923af7d40..f4914c1ea71 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,9 +11,11 @@ protobuf = "3.25.8" [libraries] android-annotations = "com.google.android:annotations:4.1.1.4" # androidx-annotation 1.9.1+ uses Kotlin and requires Android Gradle Plugin 9+ +# checkForUpdates: androidx-annotation:1.9.0 androidx-annotation = "androidx.annotation:annotation:1.9.0" # 1.15.0 requires libraries and applications that depend on it to compile against # version 35 or later of the Android APIs. +# checkForUpdates: androidx-core:1.13.+ androidx-core = "androidx.core:core:1.13.1" # androidx-lifecycle 2.9+ requires Java 17 androidx-lifecycle-common = "androidx.lifecycle:lifecycle-common:2.8.7" @@ -33,15 +35,19 @@ cronet-api = "org.chromium.net:cronet-api:119.6045.31" cronet-embedded = "org.chromium.net:cronet-embedded:119.6045.31" errorprone-annotations = "com.google.errorprone:error_prone_annotations:2.36.0" # error-prone 2.32.0+ require Java 17+ +# checkForUpdates: errorprone-core:2.31.+ errorprone-core = "com.google.errorprone:error_prone_core:2.31.0" google-api-protos = "com.google.api.grpc:proto-google-common-protos:2.59.2" # google-auth-library 1.25.0+ requires error_prone_annotations 2.31.0+, which # breaks the Android build +# checkForUpdates: google-auth-credentials:1.24.+ google-auth-credentials = "com.google.auth:google-auth-library-credentials:1.24.1" +# checkForUpdates: google-auth-oauth2Http:1.24.+ google-auth-oauth2Http = "com.google.auth:google-auth-library-oauth2-http:1.24.1" # Release notes: https://cloud.google.com/logging/docs/release-notes google-cloud-logging = "com.google.cloud:google-cloud-logging:3.23.1" # 2.13.0 requires error_prone_annotations:2.37.0, but we are stuck with 2.36.0 +# checkForUpdates: gson:2.12.+ gson = "com.google.code.gson:gson:2.12.1" # 33.4.8 requires com.google.errorprone:error_prone_annotations:2.36.0 guava = "com.google.guava:guava:33.4.8-android" @@ -52,9 +58,11 @@ guava-testlib = "com.google.guava:guava-testlib:33.4.8-android" guava-jre = "com.google.guava:guava:33.4.8-jre" hdrhistogram = "org.hdrhistogram:HdrHistogram:2.2.2" # 6.0.0+ use java.lang.Deprecated forRemoval and since from Java 9 +# checkForUpdates: jakarta-servlet-api:5.+ jakarta-servlet-api = "jakarta.servlet:jakarta.servlet-api:5.0.0" javax-servlet-api = "javax.servlet:javax.servlet-api:4.0.1" # 12.0.0+ require Java 17+ +# checkForUpdates: jetty-client:11.+ jetty-client = "org.eclipse.jetty:jetty-client:11.0.24" jetty-http2-server = "org.eclipse.jetty.http2:jetty-http2-server:12.0.23" jetty-http2-server10 = "org.eclipse.jetty.http2:http2-server:10.0.20" @@ -79,6 +87,7 @@ netty-transport-epoll = { module = "io.netty:netty-transport-native-epoll", vers netty-unix-common = { module = "io.netty:netty-transport-native-unix-common", version.ref = "netty" } okhttp = "com.squareup.okhttp:okhttp:2.7.5" # okio 3.5+ uses Kotlin 1.9+ which requires Android Gradle Plugin 9+ +# checkForUpdates: okio:3.4.+ okio = "com.squareup.okio:okio:3.4.0" opencensus-api = { module = "io.opencensus:opencensus-api", version.ref = "opencensus" } opencensus-contrib-grpc-metrics = { module = "io.opencensus:opencensus-contrib-grpc-metrics", version.ref = "opencensus" } @@ -101,14 +110,19 @@ s2a-proto = "com.google.s2a.proto.v2:s2a-proto:0.1.2" signature-android = "net.sf.androidscents.signature:android-api-level-21:5.0.1_r2" signature-java = "org.codehaus.mojo.signature:java18:1.0" # 11.0.0+ require Java 17+ +# checkForUpdates: tomcat-embed-core:10.+ tomcat-embed-core = "org.apache.tomcat.embed:tomcat-embed-core:10.1.31" +# checkForUpdates: tomcat-embed-core9:9.+ tomcat-embed-core9 = "org.apache.tomcat.embed:tomcat-embed-core:9.0.89" truth = "com.google.truth:truth:1.4.4" +# checkForUpdates: undertow-servlet22:2.2.+ undertow-servlet22 = "io.undertow:undertow-servlet:2.2.37.Final" undertow-servlet = "io.undertow:undertow-servlet:2.3.18.Final" -# Do not update: Pinned to the last version supporting Java 8. -# See https://checkstyle.sourceforge.io/releasenotes.html#Release_10.1 +# checkstyle 10.0+ requires Java 11+ +# See https://checkstyle.sourceforge.io/releasenotes_old_8-35_10-26.html#Release_10.0 +# checkForUpdates: checkstylejava8:9.+ checkstylejava8 = "com.puppycrawl.tools:checkstyle:9.3" # 2.11.0+ requires JDK 11+ (See https://github.com/google/error-prone/releases/tag/v2.11.0) +# checkForUpdates: errorprone-corejava8:2.10.+ errorprone-corejava8 = "com.google.errorprone:error_prone_core:2.10.0" From 6920620e9e273251cbb0fede70f88f48200ec3a5 Mon Sep 17 00:00:00 2001 From: Eric Anderson Date: Wed, 19 Nov 2025 07:23:19 -0800 Subject: [PATCH 2/2] Fix Java 8 build --- buildSrc/src/main/java/io/grpc/gradle/CheckForUpdatesTask.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/io/grpc/gradle/CheckForUpdatesTask.java b/buildSrc/src/main/java/io/grpc/gradle/CheckForUpdatesTask.java index fce76c1de53..b7c28dbbb2d 100644 --- a/buildSrc/src/main/java/io/grpc/gradle/CheckForUpdatesTask.java +++ b/buildSrc/src/main/java/io/grpc/gradle/CheckForUpdatesTask.java @@ -56,7 +56,7 @@ public CheckForUpdatesTask(Configuration updateConf, String catalog, RegularFile // # checkForUpdates: library-name:1.2.+ List fileComments = Files.lines(commentFile.getAsFile().toPath()) .filter(l -> l.matches("# *checkForUpdates:.*")) - .map(l -> l.replaceFirst("# *checkForUpdates:", "").strip()) + .map(l -> l.replaceFirst("# *checkForUpdates:", "").trim()) .collect(Collectors.toList()); Map aliasToVersionSelector = new HashMap<>(2*fileComments.size()); for (String comment : fileComments) {