SLING-9426 : Provide api generation reports
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/ApisJarMojo.java b/src/main/java/org/apache/sling/feature/maven/mojos/ApisJarMojo.java
index 7f9d81d..a52569d 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/ApisJarMojo.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/ApisJarMojo.java
@@ -117,7 +117,8 @@
SOURCES("sources", "java", "jar"),
JAVADOC("javadoc", "html", "jar"),
DEPENDENCIES("apideps", "txt", "ref"),
- CND("cnd", "cnd", "jar");
+ CND("cnd", "cnd", "jar"),
+ REPORT("report", "txt", "txt");
private final String id;
@@ -498,21 +499,31 @@
onArtifact(ctx, artifact);
}
- ctx.getPackagesWithoutJavaClasses().forEach( p -> getLog().info("Exported package " + p + " does not contain any java classes"));
- ctx.getPackagesWithoutSources().forEach( p -> getLog().info("Exported package " + p + " does not have sources"));
+ final List<String> globalReport = new ArrayList<>();
+
+ if ( !ctx.getPackagesWithoutJavaClassesMap().isEmpty() ) {
+ globalReport.add("The following exported packages do not contain any java classes:");
+ ctx.getPackagesWithoutJavaClassesMap().entrySet().forEach(p -> "- ".concat(p.getKey()).concat(" from ").concat(p.getValue().toMvnId()));
+ }
+ if ( !ctx.getPackagesWithoutSourcesMap().isEmpty() ) {
+ globalReport.add("The following exported packages do not have sources:");
+ ctx.getPackagesWithoutSourcesMap().entrySet().forEach(p -> "- ".concat(p.getKey()).concat(" from ").concat(p.getValue().toMvnId()));
+ }
// recollect and package stuff per region
for (final ApiRegion apiRegion : regions.listRegions()) {
+ final List<String> report = new ArrayList<>(globalReport);
+
final File regionDir = new File(featureDir, apiRegion.getName());
if (generateApiJar) {
final File apiJar = createArchive(ctx, apiRegion, ArtifactType.APIS, this.apiResources, this.useApiDependencies);
- report(ctx, apiJar, ArtifactType.APIS, apiRegion, this.useApiDependencies);
+ report(ctx, apiJar, ArtifactType.APIS, apiRegion, this.useApiDependencies, report);
}
if (generateSourceJar) {
final File sourceJar = createArchive(ctx, apiRegion, ArtifactType.SOURCES, this.apiSourceResources, this.useApiDependencies);
- report(ctx, sourceJar, ArtifactType.SOURCES, apiRegion, this.useApiDependencies);
+ report(ctx, sourceJar, ArtifactType.SOURCES, apiRegion, this.useApiDependencies, report);
}
if ( this.useApiDependencies && (this.generateApiJar || this.generateSourceJar)) {
@@ -524,12 +535,27 @@
if ( generateJavadoc(ctx, apiRegion, javadocsDir) ) {
ctx.setJavadocDir(javadocsDir);
final File javadocJar = createArchive(ctx, apiRegion, ArtifactType.JAVADOC, this.apiJavadocResources, false);
- report(ctx, javadocJar, ArtifactType.JAVADOC, apiRegion, false);
+ report(ctx, javadocJar, ArtifactType.JAVADOC, apiRegion, false, report);
} else {
getLog().warn("Javadoc JAR will NOT be generated - sources directory " + ctx.getDeflatedSourcesDir()
+ " was empty or contained no Java files!");
}
}
+
+ final ArtifactId reportId = this.buildArtifactId(ctx, apiRegion, ArtifactType.REPORT);
+ final File reportFile = new File(mainOutputDir, reportId.toMvnName());
+ if ( !report.isEmpty() ) {
+ report.stream().forEach(v -> getLog().info(v));
+ try {
+ Files.write(reportFile.toPath(), report);
+ } catch (final IOException e) {
+ throw new MojoExecutionException("Unable to write " + reportFile, e);
+ }
+ } else {
+ if ( reportFile.exists()) {
+ reportFile.delete();
+ }
+ }
}
getLog().info(MessageUtils.buffer().a("APIs JARs for Feature ").debug(feature.getId().toMvnId())
@@ -540,7 +566,8 @@
final File jarFile,
final ArtifactType artifactType,
final ApiRegion apiRegion,
- final boolean omitDependencyArtifacts)
+ final boolean omitDependencyArtifacts,
+ final List<String> report)
throws MojoExecutionException {
final List<String> packages = getPackages(jarFile, artifactType.getContentExtension());
if ( omitDependencyArtifacts ) {
@@ -566,7 +593,7 @@
getLog().info("Verified " + artifactType.getId() + " jar for region " + apiRegion.getName());
} else {
Collections.sort(missing);
- getLog().info(artifactType.getId() + " jar for region " + apiRegion.getName() + " has " + ( missing.size() + packages.size() ) + " errors:");
+ report.add(artifactType.getId() + " jar for region " + apiRegion.getName() + " has " + ( missing.size() + packages.size() ) + " errors:");
for (final ApiExport m : missing) {
final List<String> candidates = new ArrayList<>();
for(final ArtifactInfo info : ctx.getArtifactInfos()) {
@@ -577,11 +604,11 @@
}
}
}
- getLog().info("- Missing package " + m.getName() + " from bundle(s) "
+ report.add("- Missing package " + m.getName() + " from bundle(s) "
+ String.join(",", candidates));
}
for (final String m : packages) {
- getLog().info("- Wrong package " + m);
+ report.add("- Wrong package " + m);
}
}
}
@@ -756,7 +783,7 @@
// We need to record this kind of packages and ensure we don't trigger warnings for them
// when checking the api jars for correctness.
getLog().debug("No sources found in " + pck);
- ctx.getPackagesWithoutSources().add(pck);
+ ctx.getPackagesWithoutSourcesMap().put(pck, info.getId());
}
}
}
@@ -780,7 +807,7 @@
// We need to record this kind of packages and ensure we don't trigger warnings for them
// when checking the api jars for correctness.
getLog().debug("No classes found in " + pck);
- ctx.getPackagesWithoutJavaClasses().add(pck);
+ ctx.getPackagesWithoutJavaClassesMap().put(pck, info.getId());
}
}
diff --git a/src/main/java/org/apache/sling/feature/maven/mojos/apis/ApisJarContext.java b/src/main/java/org/apache/sling/feature/maven/mojos/apis/ApisJarContext.java
index 356ea6c..2dd0eba 100644
--- a/src/main/java/org/apache/sling/feature/maven/mojos/apis/ApisJarContext.java
+++ b/src/main/java/org/apache/sling/feature/maven/mojos/apis/ApisJarContext.java
@@ -193,9 +193,9 @@
private final Set<String> javadocClasspath = new HashSet<>();
- private final Set<String> packagesWithoutJavaClasses = new HashSet<>();
+ private final Map<String, ArtifactId> packagesWithoutJavaClassesMap = new HashMap<>();
- private final Set<String> packagesWithoutSources = new HashSet<>();
+ private final Map<String, ArtifactId> packagesWithoutSourcesMap = new HashMap<>();
private final File deflatedBinDir;
@@ -264,12 +264,20 @@
this.javadocDir = javadocDir;
}
+ public Map<String, ArtifactId> getPackagesWithoutJavaClassesMap() {
+ return packagesWithoutJavaClassesMap;
+ }
+
+ public Map<String, ArtifactId> getPackagesWithoutSourcesMap() {
+ return packagesWithoutSourcesMap;
+ }
+
public Set<String> getPackagesWithoutJavaClasses() {
- return packagesWithoutJavaClasses;
+ return packagesWithoutJavaClassesMap.keySet();
}
public Set<String> getPackagesWithoutSources() {
- return packagesWithoutSources;
+ return packagesWithoutSourcesMap.keySet();
}
public ArtifactInfo addArtifactInfo(final Artifact artifact) {