Skip to content

Commit

Permalink
Add fix parameter to checkClassUniqueness (#2781)
Browse files Browse the repository at this point in the history
  • Loading branch information
pkoenig10 authored May 1, 2024
1 parent 2bf0044 commit 0004d07
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public final void apply(Project project) {
TaskProvider<CheckClassUniquenessLockTask> checkClassUniqueness = project.getTasks()
.register("checkClassUniqueness", CheckClassUniquenessLockTask.class, task -> {
task.jarClassHasher.set(jarClassHasher);
task.shouldFix.convention(
project.getGradle().getStartParameter().isWriteDependencyLocks());
task.usesService(jarClassHasher);
});
project.getPlugins().apply(LifecycleBasePlugin.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.options.Option;
import org.gradle.util.GFileUtils;

@CacheableTask
public class CheckClassUniquenessLockTask extends DefaultTask {

private static final String HEADER = "# Danger! Multiple jars contain identically named classes. This may "
+ "cause different behaviour depending on classpath ordering.\n"
+ "# Run ./gradlew checkClassUniqueness --write-locks to update this file\n\n";
+ "# Run ./gradlew checkClassUniqueness --fix to update this file\n\n";

// not marking this as an Input, because we want to re-run if the *contents* of a configuration changes
@SuppressWarnings("VisibilityModifier")
Expand All @@ -61,11 +62,15 @@ public class CheckClassUniquenessLockTask extends DefaultTask {
@SuppressWarnings("VisibilityModifier")
public final Property<JarClassHasher> jarClassHasher;

@SuppressWarnings("VisibilityModifier")
public final Property<Boolean> shouldFix;

private final File lockFile;

public CheckClassUniquenessLockTask() {
this.configurations = getProject().getObjects().setProperty(Configuration.class);
this.jarClassHasher = getProject().getObjects().property(JarClassHasher.class);
this.shouldFix = getProject().getObjects().property(Boolean.class);
this.lockFile = getProject().file("baseline-class-uniqueness.lock");
onlyIf(new Spec<Task>() {
@Override
Expand Down Expand Up @@ -93,6 +98,11 @@ public final File getLockFile() {
return lockFile;
}

@Option(option = "fix", description = "Whether to apply the suggested fix to baseline-class-uniqueness.lock")
public final void setShouldFix(boolean shouldFix) {
this.shouldFix.set(shouldFix);
}

@TaskAction
public final void doIt() {
ImmutableSortedMap<String, Optional<String>> resultsByConfiguration = configurations.get().stream()
Expand Down Expand Up @@ -153,7 +163,7 @@ private String clashingJarHeader(Set<ModuleVersionIdentifier> clashingJars) {
}

private void ensureLockfileContains(String expected) {
if (getProject().getGradle().getStartParameter().isWriteDependencyLocks()) {
if (shouldFix.get()) {
GFileUtils.writeFile(expected, lockFile);
getLogger()
.lifecycle("Updated {}", getProject().getRootDir().toPath().relativize(lockFile.toPath()));
Expand All @@ -163,9 +173,9 @@ private void ensureLockfileContains(String expected) {
if (!lockFile.exists()) {
throw new ExceptionWithSuggestion(
"baseline-class-uniqueness detected multiple jars containing identically named classes."
+ " Please resolve these problems, or run `./gradlew checkClassUniqueness --write-locks`"
+ " Please resolve these problems, or run `./gradlew checkClassUniqueness --fix`"
+ "to accept them:\n\n " + expected,
"./gradlew checkClassUniqueness --write-locks");
"./gradlew checkClassUniqueness --fix");
}

String onDisk = GFileUtils.readFile(lockFile);
Expand All @@ -177,7 +187,9 @@ private void ensureLockfileContains(String expected) {
String.join(
"\n",
String.format(
"%s is out of date, please run ` " + "to update this file. The diff is:", lockFile),
"%s is out of date, please run `./gradlew checkClassUniqueness --fix` to"
+ " update this file. The diff is:",
lockFile),
"",
String.join(
"\n",
Expand All @@ -190,13 +202,13 @@ private void ensureLockfileContains(String expected) {
"",
"Expected was:",
expected),
"./gradlew checkClassUniqueness --write-locks");
"./gradlew checkClassUniqueness --fix");
}
}

private void ensureLockfileDoesNotExist() {
if (lockFile.exists()) {
if (getProject().getGradle().getStartParameter().isWriteDependencyLocks()) {
if (shouldFix.get()) {
GFileUtils.deleteQuietly(lockFile);
getLogger()
.lifecycle(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,37 @@ class BaselineClassUniquenessPluginIntegrationTest extends AbstractPluginTest {
}
""".stripIndent()

def 'detect duplicates in two external jars, then --fix captures'() {
File lockfile = new File(projectDir, 'baseline-class-uniqueness.lock')

when:
buildFile << standardBuildFile
buildFile << """
dependencies {
api group: 'javax.el', name: 'javax.el-api', version: '3.0.0'
api group: 'javax.servlet.jsp', name: 'jsp-api', version: '2.1'
}
""".stripIndent()
BuildResult result = with('check', '-s').buildAndFail()

then:
result.getOutput().contains("baseline-class-uniqueness detected multiple jars containing identically named classes.")
result.getOutput().contains("[javax.el:javax.el-api, javax.servlet.jsp:jsp-api]")
result.getOutput().contains("javax.el.ArrayELResolver");
!lockfile.exists()

when:
with("checkClassUniqueness", "--fix").build()

then:
lockfile.exists()
File expected = new File("src/test/resources/com/palantir/baseline/baseline-class-uniqueness.expected.lock")
if (Boolean.getBoolean("recreate")) {
GFileUtils.writeFile(lockfile.text, expected)
}
lockfile.text == expected.text
}

def 'detect duplicates in two external jars, then --write-locks captures'() {
File lockfile = new File(projectDir, 'baseline-class-uniqueness.lock')

Expand All @@ -56,9 +87,11 @@ class BaselineClassUniquenessPluginIntegrationTest extends AbstractPluginTest {
result.getOutput().contains("javax.el.ArrayELResolver");
!lockfile.exists()

when:
with("checkClassUniqueness", "--write-locks").build()
lockfile.exists()

then:
lockfile.exists()
File expected = new File("src/test/resources/com/palantir/baseline/baseline-class-uniqueness.expected.lock")
if (Boolean.getBoolean("recreate")) {
GFileUtils.writeFile(lockfile.text, expected)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Danger! Multiple jars contain identically named classes. This may cause different behaviour depending on classpath ordering.
# Run ./gradlew checkClassUniqueness --write-locks to update this file
# Run ./gradlew checkClassUniqueness --fix to update this file

## runtimeClasspath
[javax.el:javax.el-api, javax.servlet.jsp:jsp-api]
Expand Down

0 comments on commit 0004d07

Please sign in to comment.