in src/main/java/org/apache/maven/plugins/artifact/buildinfo/CompareMojo.java [161:256]
private void compareWithReference(Map<Artifact, String> artifacts, File referenceBuildinfo)
throws MojoExecutionException {
Properties actual = BuildInfoWriter.loadOutputProperties(buildinfoFile);
Properties reference = BuildInfoWriter.loadOutputProperties(referenceBuildinfo);
int ok = 0;
List<String> okFilenames = new ArrayList<>();
List<String> koFilenames = new ArrayList<>();
List<String> diffoscopes = new ArrayList<>();
List<String> ignored = new ArrayList<>();
File referenceDir = referenceBuildinfo.getParentFile();
for (Map.Entry<Artifact, String> entry : artifacts.entrySet()) {
Artifact artifact = entry.getKey();
String prefix = entry.getValue();
if (prefix == null) {
// ignored file
ignored.add(getArtifactFilename(artifact));
continue;
}
String[] checkResult = checkArtifact(artifact, prefix, reference, actual, referenceDir);
String filename = checkResult[0];
String diffoscope = checkResult[1];
if (diffoscope == null) {
ok++;
okFilenames.add(filename);
} else {
koFilenames.add(filename);
diffoscopes.add(diffoscope);
}
}
int ko = artifacts.size() - ok - ignored.size();
int missing = reference.size() / 3 /* 3 property keys par file: filename, length and checksums.sha512 */;
if (ko + missing > 0) {
getLog().error("Reproducible Build output summary: "
+ MessageUtils.buffer().success(ok + " files ok")
+ ", " + MessageUtils.buffer().failure(ko + " different")
+ ((missing == 0) ? "" : (", " + MessageUtils.buffer().failure(missing + " missing")))
+ ((ignored.isEmpty()) ? "" : (", " + MessageUtils.buffer().warning(ignored.size() + " ignored"))));
getLog().error("see "
+ MessageUtils.buffer()
.project("diff " + relative(referenceBuildinfo) + " " + relative(buildinfoFile))
.build());
getLog().error("see also https://maven.apache.org/guides/mini/guide-reproducible-builds.html");
} else {
getLog().info("Reproducible Build output summary: "
+ MessageUtils.buffer().success(ok + " files ok")
+ ((ignored.isEmpty()) ? "" : (", " + MessageUtils.buffer().warning(ignored.size() + " ignored"))));
}
// save .compare file
File buildcompare = new File(
buildinfoFile.getParentFile(), buildinfoFile.getName().replaceFirst(".buildinfo$", ".buildcompare"));
try (PrintWriter p = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(Files.newOutputStream(buildcompare.toPath()), StandardCharsets.UTF_8)))) {
p.println("version=" + project.getVersion());
p.println("ok=" + ok);
p.println("ko=" + ko);
p.println("ignored=" + ignored.size());
p.println("okFiles=\"" + String.join(" ", okFilenames) + '"');
p.println("koFiles=\"" + String.join(" ", koFilenames) + '"');
p.println("ignoredFiles=\"" + String.join(" ", ignored) + '"');
Properties ref = new Properties();
if (referenceBuildinfo != null) {
try (InputStream in = Files.newInputStream(referenceBuildinfo.toPath())) {
ref.load(in);
} catch (IOException e) {
// nothing
}
}
String v = ref.getProperty("java.version");
if (v != null) {
p.println("reference_java_version=\"" + v + '"');
}
v = ref.getProperty("os.name");
if (v != null) {
p.println("reference_os_name=\"" + v + '"');
}
for (String diffoscope : diffoscopes) {
p.print("# ");
p.println(diffoscope);
}
getLog().info("Reproducible Build output comparison saved to " + buildcompare);
} catch (IOException e) {
throw new MojoExecutionException("Error creating file " + buildcompare, e);
}
copyAggregateToRoot(buildcompare);
if (fail && (ko + missing > 0)) {
throw new MojoExecutionException("Build artifacts are different from reference");
}
}