Ensure packages and classes are traversed in order.
This ensures the generated JSON is stable over regeneration to minimize
diffs.
package com.yahoo.abicheck.mojo;
+import com.google.common.collect.Ordering;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
@@ -15,11 +16,14 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.jar.JarFile;
+import java.util.stream.Collectors;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
@@ -132,14 +136,19 @@ public class AbiCheck extends AbstractMojo {
Map<String, JavaClassSignature> signatures = new LinkedHashMap<>();
if (isPublicAbiPackage(pkg, publicApiAnnotation)) {
PublicSignatureCollector collector = new PublicSignatureCollector();
- for (ClassFile klazz : pkg.getClassFiles()) {
+ List<ClassFileTree.ClassFile> sortedClassFiles = pkg.getClassFiles().stream()
+ .sorted(Comparator.comparing(ClassFile::getName)).collect(Collectors.toList());
+ for (ClassFile klazz : sortedClassFiles) {
try (InputStream is = klazz.getInputStream()) {
new ClassReader(is).accept(collector, 0);
}
}
signatures.putAll(collector.getClassSignatures());
}
- for (ClassFileTree.Package subPkg : pkg.getSubPackages()) {
+ List<ClassFileTree.Package> sortedSubPackages = pkg.getSubPackages().stream()
+ .sorted(Comparator.comparing(Package::getFullyQualifiedName))
+ .collect(Collectors.toList());
+ for (ClassFileTree.Package subPkg : sortedSubPackages) {
signatures.putAll(collectPublicAbiSignatures(subPkg, publicApiAnnotation));
}
return signatures;
