diff --git a/changelog/@unreleased/pr-2724.v2.yml b/changelog/@unreleased/pr-2724.v2.yml new file mode 100644 index 000000000..154864338 --- /dev/null +++ b/changelog/@unreleased/pr-2724.v2.yml @@ -0,0 +1,5 @@ +type: improvement +improvement: + description: Integrates with gradle-failure-reports. Adds ExceptionWithSuggestion. + links: + - https://github.com/palantir/gradle-baseline/pull/2724 diff --git a/gradle-baseline-java/build.gradle b/gradle-baseline-java/build.gradle index f6779e41e..3193656aa 100644 --- a/gradle-baseline-java/build.gradle +++ b/gradle-baseline-java/build.gradle @@ -26,6 +26,7 @@ dependencies { implementation 'org.ow2.asm:asm' implementation 'com.googlecode.java-diff-utils:diffutils' implementation 'com.palantir.gradle.utils:lazily-configured-mapping' + implementation 'com.palantir.gradle.failure-reports:gradle-failure-reports-exceptions' runtimeOnly 'com.palantir.javaformat:gradle-palantir-java-format' diff --git a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckClassUniquenessLockTask.java b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckClassUniquenessLockTask.java index 55d8230b8..a4b50763a 100644 --- a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckClassUniquenessLockTask.java +++ b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckClassUniquenessLockTask.java @@ -20,6 +20,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSortedMap; import com.palantir.baseline.services.JarClassHasher; +import com.palantir.gradle.failurereports.exceptions.ExceptionWithSuggestion; import difflib.DiffUtils; import difflib.Patch; import java.io.File; @@ -160,10 +161,11 @@ private void ensureLockfileContains(String expected) { } if (!lockFile.exists()) { - throw new GradleException("baseline-class-uniqueness detected multiple jars containing identically named " - + "classes. Please resolve these problems, or run `./gradlew checkClassUniqueness " - + "--write-locks` to accept them:\n\n" - + expected); + throw new ExceptionWithSuggestion( + "baseline-class-uniqueness detected multiple jars containing identically named classes." + + " Please resolve these problems, or run `./gradlew checkClassUniqueness --write-locks`" + + "to accept them:\n\n " + expected, + "./gradlew checkClassUniqueness --write-locks"); } String onDisk = GFileUtils.readFile(lockFile); @@ -171,23 +173,24 @@ private void ensureLockfileContains(String expected) { List onDiskLines = Splitter.on('\n').splitToList(onDisk); Patch diff = DiffUtils.diff(onDiskLines, Splitter.on('\n').splitToList(expected)); - throw new GradleException(String.join( - "\n", - String.format( - "%s is out of date, please run `./gradlew checkClassUniqueness --write-locks` " - + "to update this file. The diff is:", - lockFile), - "", + throw new ExceptionWithSuggestion( String.join( "\n", - DiffUtils.generateUnifiedDiff("on disk", "expected", onDiskLines, diff, Integer.MAX_VALUE)), - "", - "On disk was:", - "", - onDisk, - "", - "Expected was:", - expected)); + String.format( + "%s is out of date, please run ` " + "to update this file. The diff is:", lockFile), + "", + String.join( + "\n", + DiffUtils.generateUnifiedDiff( + "on disk", "expected", onDiskLines, diff, Integer.MAX_VALUE)), + "", + "On disk was:", + "", + onDisk, + "", + "Expected was:", + expected), + "./gradlew checkClassUniqueness --write-locks"); } } diff --git a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckExplicitSourceCompatibilityTask.java b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckExplicitSourceCompatibilityTask.java index 38a6384e1..b92e54987 100644 --- a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckExplicitSourceCompatibilityTask.java +++ b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckExplicitSourceCompatibilityTask.java @@ -17,6 +17,7 @@ package com.palantir.baseline.tasks; import com.palantir.baseline.plugins.javaversions.BaselineJavaVersion; +import com.palantir.gradle.failurereports.exceptions.ExceptionWithSuggestion; import java.io.IOException; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; @@ -25,7 +26,6 @@ import java.util.Collections; import javax.inject.Inject; import org.gradle.api.DefaultTask; -import org.gradle.api.GradleException; import org.gradle.api.JavaVersion; import org.gradle.api.Task; import org.gradle.api.model.ObjectFactory; @@ -130,20 +130,18 @@ public final void taskAction() throws IOException { StandardOpenOption.CREATE); return; } - - throw new GradleException(String.format( - "%s must set sourceCompatibility explicitly in '%s', " - + "otherwise compilation will not be reproducible but instead depends on the Java version " - + "that Gradle is currently running with (%s). To auto-fix, run%n" - + "%n" - + " ./gradlew %s --fix%n" - + "%n" - + "This will automatically add a suggested line " - + "(you may need to adjust the number, e.g. to '1.8' for maximum compatibility).", - getProject(), - getProject().getRootProject().relativePath(getProject().getBuildFile()), - JavaVersion.current(), - getPath())); + String suggestion = String.format("./gradlew %s --fix", getPath()); + throw new ExceptionWithSuggestion( + String.format( + "%s must set sourceCompatibility explicitly in '%s', otherwise compilation will not be" + + " reproducible but instead depends on the Java version that Gradle is currently running" + + " with (%s). To auto-fix, run%n%n %s%n%nThis will automatically add a suggested line" + + " (you may need to adjust the number, e.g. to '1.8' for maximum compatibility).", + getProject(), + getProject().getRootProject().relativePath(getProject().getBuildFile()), + JavaVersion.current(), + suggestion), + suggestion); } private JavaVersion getRawSourceCompat() { diff --git a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckImplicitDependenciesTask.java b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckImplicitDependenciesTask.java index 7e5fa4897..ba29f9a6e 100644 --- a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckImplicitDependenciesTask.java +++ b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckImplicitDependenciesTask.java @@ -18,6 +18,7 @@ import com.google.common.collect.Streams; import com.palantir.baseline.plugins.BaselineExactDependencies; +import com.palantir.gradle.failurereports.exceptions.ExceptionWithSuggestion; import java.nio.file.Path; import java.util.Collections; import java.util.Comparator; @@ -26,7 +27,6 @@ import java.util.Set; import java.util.stream.Collectors; import org.gradle.api.DefaultTask; -import org.gradle.api.GradleException; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.ResolvedArtifact; import org.gradle.api.artifacts.ResolvedDependency; @@ -90,11 +90,12 @@ public final void checkImplicitDependencies() { .map(artifact -> getSuggestionString(artifact)) .sorted() .collect(Collectors.joining("\n", " dependencies {\n", "\n }")); - - throw new GradleException(String.format( - "Found %d implicit dependencies - consider adding the following explicit " - + "dependencies to '%s', or avoid using classes from these jars:\n%s", - usedButUndeclared.size(), buildFile(), suggestion)); + throw new ExceptionWithSuggestion( + String.format( + "Found %d implicit dependencies - consider adding the following explicit " + + "dependencies to '%s', or avoid using classes from these jars:\n%s", + usedButUndeclared.size(), buildFile(), suggestion), + buildFile().toString()); } } diff --git a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckUnusedDependenciesTask.java b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckUnusedDependenciesTask.java index e7dc24fa1..97ec7b2d6 100644 --- a/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckUnusedDependenciesTask.java +++ b/gradle-baseline-java/src/main/groovy/com/palantir/baseline/tasks/CheckUnusedDependenciesTask.java @@ -20,6 +20,7 @@ import com.google.common.collect.Sets; import com.google.common.collect.Streams; import com.palantir.baseline.plugins.BaselineExactDependencies; +import com.palantir.gradle.failurereports.exceptions.ExceptionWithSuggestion; import java.nio.file.Path; import java.util.Collections; import java.util.Comparator; @@ -28,7 +29,6 @@ import java.util.Set; import java.util.stream.Collectors; import org.gradle.api.DefaultTask; -import org.gradle.api.GradleException; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.ResolvedArtifact; import org.gradle.api.artifacts.ResolvedDependency; @@ -130,7 +130,7 @@ public final void checkUnusedDependencies() { .append("\n")); } } - throw new GradleException(builder.toString()); + throw new ExceptionWithSuggestion(builder.toString(), buildFile().toString()); } } diff --git a/versions.lock b/versions.lock index 8c1418b54..0c363e46c 100644 --- a/versions.lock +++ b/versions.lock @@ -27,6 +27,7 @@ com.google.protobuf:protobuf-java:3.19.6 (1 constraints: 301169c9) com.googlecode.concurrent-trees:concurrent-trees:2.6.1 (1 constraints: 761166da) com.googlecode.java-diff-utils:diffutils:1.3.0 (1 constraints: 0605f935) com.googlecode.javaewah:JavaEWAH:1.1.12 (1 constraints: 750eee5e) +com.palantir.gradle.failure-reports:gradle-failure-reports-exceptions:1.2.0 (1 constraints: 0505f635) com.palantir.gradle.utils:lazily-configured-mapping:0.1.0 (1 constraints: 0305ee35) com.palantir.javaformat:gradle-palantir-java-format:1.1.0 (1 constraints: 0405f335) com.palantir.javaformat:palantir-java-format-spi:1.1.0 (1 constraints: 711560be) diff --git a/versions.props b/versions.props index 93bc5e7c1..53e0e761a 100644 --- a/versions.props +++ b/versions.props @@ -16,6 +16,7 @@ com.googlecode.java-diff-utils:diffutils = 1.3.0 com.puppycrawl.tools:checkstyle = 10.12.5 com.palantir.gradle.utils:* = 0.1.0 com.uber.nullaway:nullaway = 0.10.19 +com.palantir.gradle.failure-reports:* = 1.2.0 # test deps com.fasterxml.jackson.*:* = 2.15.3