You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gg...@apache.org on 2019/01/23 15:34:06 UTC
[karaf] branch master updated: [KARAF-6109] Combine 3 reports
(possible more) in single XML
This is an automated email from the ASF dual-hosted git repository.
ggrzybek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/karaf.git
The following commit(s) were added to refs/heads/master by this push:
new 2489f0b [KARAF-6109] Combine 3 reports (possible more) in single XML
2489f0b is described below
commit 2489f0b40eaa6ccbdb8d7c992f2086b99736a6d6
Author: Grzegorz Grzybek <gr...@gmail.com>
AuthorDate: Wed Jan 23 16:33:47 2019 +0100
[KARAF-6109] Combine 3 reports (possible more) in single XML
---
assemblies/apache-karaf/pom.xml | 1 +
.../org/apache/karaf/profile/assembly/Builder.java | 279 ++++++++++++++-------
profile/src/main/resources/bundle-report.xslt | 194 ++++++++++----
.../org/apache/karaf/tooling/AssemblyMojo.java | 14 ++
4 files changed, 350 insertions(+), 138 deletions(-)
diff --git a/assemblies/apache-karaf/pom.xml b/assemblies/apache-karaf/pom.xml
index e4bd2da..2871373 100644
--- a/assemblies/apache-karaf/pom.xml
+++ b/assemblies/apache-karaf/pom.xml
@@ -161,6 +161,7 @@
</libraries>
<javase>1.8</javase>
<generateConsistencyReport>${project.build.directory}</generateConsistencyReport>
+ <consistencyReportProjectName>Apache Karaf (full)</consistencyReportProjectName>
</configuration>
</plugin>
</plugins>
diff --git a/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java b/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
index 42fb74f..b802c53 100644
--- a/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
+++ b/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
@@ -52,7 +52,9 @@ import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.function.BiPredicate;
import java.util.function.Function;
+import java.util.function.Predicate;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.regex.Pattern;
@@ -306,6 +308,8 @@ public class Builder {
List<String> pidsToExtract = new LinkedList<>();
boolean writeProfiles;
String generateConsistencyReport;
+ String consistencyReportProjectName;
+ String consistencyReportProjectVersion;
private ScheduledExecutorService executor;
private DownloadManager manager;
@@ -577,6 +581,22 @@ public class Builder {
}
/**
+ * Configure project name to be used in consistency report
+ * @param consistencyReportProjectName
+ */
+ public void setConsistencyReportProjectName(String consistencyReportProjectName) {
+ this.consistencyReportProjectName = consistencyReportProjectName;
+ }
+
+ /**
+ * Configure project version to be used in consistency report
+ * @param consistencyReportProjectVersion
+ */
+ public void setConsistencyReportProjectVersion(String consistencyReportProjectVersion) {
+ this.consistencyReportProjectVersion = consistencyReportProjectVersion;
+ }
+
+ /**
* Configure Karaf version to target. This impacts the way some configuration files are generated.
* @param karafVersion
* @return
@@ -1107,13 +1127,19 @@ public class Builder {
if (generateConsistencyReport != null) {
File directory = new File(generateConsistencyReport);
- if (directory.isDirectory()) {
- LOGGER.info("Writing bundle report");
- generateConsistencyReport(karRepositories, allInstalledFeatures, installedProfile, new File(directory, "bundle-report-full.xml"), true);
- generateConsistencyReport(karRepositories, allInstalledFeatures, installedProfile, new File(directory, "bundle-report.xml"), false);
- Files.copy(getClass().getResourceAsStream("/bundle-report.xslt"),
- directory.toPath().resolve("bundle-report.xslt"),
- StandardCopyOption.REPLACE_EXISTING);
+ if (directory.isFile()) {
+ LOGGER.warn("Can't generate consistency report into {} - it's not a directory", generateConsistencyReport);
+ } else {
+ if (!directory.exists()) {
+ directory.mkdirs();
+ }
+ if (directory.isDirectory()) {
+ LOGGER.info("Writing bundle report");
+ generateConsistencyReport(karRepositories, allInstalledFeatures, installedProfile, new File(directory, "bundle-report.xml"));
+ Files.copy(getClass().getResourceAsStream("/bundle-report.xslt"),
+ directory.toPath().resolve("bundle-report.xslt"),
+ StandardCopyOption.REPLACE_EXISTING);
+ }
}
}
}
@@ -1121,9 +1147,11 @@ public class Builder {
/**
* Produces human readable XML with <em>feature consistency report</em>.
* @param repositories
+ * @param allInstalledFeatures
+ * @param installedProfile
* @param result
*/
- public void generateConsistencyReport(Map<String, Features> repositories, Set<Feature> allInstalledFeatures, Profile installedProfile, File result, boolean full) {
+ public void generateConsistencyReport(Map<String, Features> repositories, Set<Feature> allInstalledFeatures, Profile installedProfile, File result) {
Profile installedOverlay = Profiles.getOverlay(installedProfile, allProfiles, environment);
Profile installedEffective = Profiles.getEffective(installedOverlay, false);
@@ -1134,107 +1162,174 @@ public class Builder {
FeatureSelector selector = new FeatureSelector(allInstalledFeatures);
Set<Feature> effectiveInstalledFeatures = selector.getMatching(installFeatures);
- Map<String, String> featureId2repository = new HashMap<>();
- // list of feature IDs containing given bundle URIs
- Map<String, Set<String>> bundle2featureId = new TreeMap<>(new URIAwareComparator());
- // map of groupId/artifactId to full URI list to detect "duplicates"
- Map<String, List<String>> ga2uri = new TreeMap<>();
- Set<String> haveDuplicates = new HashSet<>();
-
- // collect closure of bundles and features
- repositories.forEach((name, features) -> {
- if (full || !features.isBlacklisted()) {
- features.getFeature().forEach(feature -> {
- if (full || (!feature.isBlacklisted() && effectiveInstalledFeatures.contains(feature))) {
- featureId2repository.put(feature.getId(), name);
- feature.getBundle().forEach(bundle -> {
- // normal bundles of feature
- bundle2featureId.computeIfAbsent(bundle.getLocation().trim(), k -> new TreeSet<>()).add(feature.getId());
- });
- feature.getConditional().forEach(cond -> {
- cond.asFeature().getBundles().forEach(bundle -> {
- // conditional bundles of feature
- bundle2featureId.computeIfAbsent(bundle.getLocation().trim(), k -> new TreeSet<>()).add(feature.getId());
- });
- });
- }
- });
- }
- });
- // collect bundle URIs - for now, only wrap:mvn: and mvn: are interesting
- bundle2featureId.keySet().forEach(uri -> {
- String originalUri = uri;
- if (uri.startsWith("wrap:mvn:")) {
- uri = uri.substring(5);
- if (uri.indexOf(";") > 0) {
- uri = uri.substring(0, uri.indexOf(";"));
- }
- if (uri.indexOf("$") > 0) {
- uri = uri.substring(0, uri.indexOf("$"));
- }
- }
- if (uri.startsWith("mvn:")) {
- try {
- LocationPattern pattern = new LocationPattern(uri);
- String ga = String.format("%s/%s", pattern.getGroupId(), pattern.getArtifactId());
- ga2uri.computeIfAbsent(ga, k -> new LinkedList<>()).add(originalUri);
- } catch (IllegalArgumentException ignored) {
- /*
- <!-- hibernate-validator-osgi-karaf-features-5.3.4.Final-features.xml -->
- <feature name="hibernate-validator-paranamer" version="5.3.4.Final">
- <feature>hibernate-validator</feature>
- <bundle>wrap:mvn:com.thoughtworks.paranamer:paranamer:2.8</bundle>
- </feature>
- */
- }
- }
- });
- ga2uri.values().forEach(l -> {
- if (l.size() > 1) {
- haveDuplicates.addAll(l);
- }
- });
-
if (result == null) {
return;
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(result))) {
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
writer.write("<?xml-stylesheet type=\"text/xsl\" href=\"bundle-report.xslt\"?>\n");
- writer.write("<consistency-report xmlns=\"urn:apache:karaf:consistency:1.0\">\n");
- writer.write(" <duplicates>\n");
- ga2uri.forEach((key, uris) -> {
- if (uris.size() > 1) {
- try {
- writer.write(String.format(" <duplicate ga=\"%s\">\n", key));
- for (String uri : uris) {
- writer.write(String.format(" <bundle uri=\"%s\">\n", sanitize(uri)));
- for (String fid : bundle2featureId.get(uri)) {
- writer.write(String.format(" <feature repository=\"%s\">%s</feature>\n", featureId2repository.get(fid), fid));
+ writer.write("<consistency-report xmlns=\"urn:apache:karaf:consistency:1.0\" project=\"" + consistencyReportProjectName + "\" version=\"" + consistencyReportProjectVersion + "\">\n");
+
+ ReportFlavor[] flavors = new ReportFlavor[] {
+ all,
+ notBlacklisted,
+ new ReportFlavor() {
+ @Override
+ public String name() {
+ return "installed";
+ }
+
+ @Override
+ public boolean include(Features repository) {
+ return !repository.isBlacklisted();
+ }
+
+ @Override
+ public boolean include(Feature feature) {
+ return !feature.isBlacklisted()
+ && effectiveInstalledFeatures.contains(feature);
+ }
+ }
+ };
+
+ for (ReportFlavor flavor : flavors) {
+ writer.write("<report flavor=\"" + flavor.name() + "\">\n");
+
+ Map<String, String> featureId2repository = new HashMap<>();
+ // list of feature IDs containing given bundle URIs
+ Map<String, Set<String>> bundle2featureId = new TreeMap<>(new URIAwareComparator());
+ // map of groupId/artifactId to full URI list to detect "duplicates"
+ Map<String, List<String>> ga2uri = new TreeMap<>();
+ Set<String> haveDuplicates = new HashSet<>();
+
+ // collect closure of bundles and features
+ repositories.forEach((name, features) -> {
+ if (flavor.include(features)) {
+ features.getFeature().forEach(feature -> {
+ if (flavor.include(feature)) {
+ featureId2repository.put(feature.getId(), name);
+ feature.getBundle().forEach(bundle -> {
+ // normal bundles of feature
+ bundle2featureId.computeIfAbsent(bundle.getLocation().trim(), k -> new TreeSet<>()).add(feature.getId());
+ });
+ feature.getConditional().forEach(cond -> {
+ cond.asFeature().getBundles().forEach(bundle -> {
+ // conditional bundles of feature
+ bundle2featureId.computeIfAbsent(bundle.getLocation().trim(), k -> new TreeSet<>()).add(feature.getId());
+ });
+ });
}
- writer.write(" </bundle>\n");
+ });
+ }
+ });
+ // collect bundle URIs - for now, only wrap:mvn: and mvn: are interesting
+ bundle2featureId.keySet().forEach(uri -> {
+ String originalUri = uri;
+ if (uri.startsWith("wrap:mvn:")) {
+ uri = uri.substring(5);
+ if (uri.indexOf(";") > 0) {
+ uri = uri.substring(0, uri.indexOf(";"));
+ }
+ if (uri.indexOf("$") > 0) {
+ uri = uri.substring(0, uri.indexOf("$"));
}
- writer.write(" </duplicate>\n");
- } catch (IOException e) {
}
+ if (uri.startsWith("mvn:")) {
+ try {
+ LocationPattern pattern = new LocationPattern(uri);
+ String ga = String.format("%s/%s", pattern.getGroupId(), pattern.getArtifactId());
+ ga2uri.computeIfAbsent(ga, k -> new LinkedList<>()).add(originalUri);
+ } catch (IllegalArgumentException ignored) {
+ /*
+ <!-- hibernate-validator-osgi-karaf-features-5.3.4.Final-features.xml -->
+ <feature name="hibernate-validator-paranamer" version="5.3.4.Final">
+ <feature>hibernate-validator</feature>
+ <bundle>wrap:mvn:com.thoughtworks.paranamer:paranamer:2.8</bundle>
+ </feature>
+ */
+ }
+ }
+ });
+ ga2uri.values().forEach(l -> {
+ if (l.size() > 1) {
+ haveDuplicates.addAll(l);
+ }
+ });
+ writer.write(" <duplicates>\n");
+ ga2uri.forEach((key, uris) -> {
+ if (uris.size() > 1) {
+ try {
+ writer.write(String.format(" <duplicate ga=\"%s\">\n", key));
+ for (String uri : uris) {
+ writer.write(String.format(" <bundle uri=\"%s\">\n", sanitize(uri)));
+ for (String fid : bundle2featureId.get(uri)) {
+ writer.write(String.format(" <feature repository=\"%s\">%s</feature>\n", featureId2repository.get(fid), fid));
+ }
+ writer.write(" </bundle>\n");
+ }
+ writer.write(" </duplicate>\n");
+ } catch (IOException ignored) {
+ }
+ }
+ });
+ writer.write(" </duplicates>\n");
+ writer.write(" <bundles>\n");
+ for (String uri : bundle2featureId.keySet()) {
+ writer.write(String.format(" <bundle uri=\"%s\" duplicate=\"%b\">\n", sanitize(uri), haveDuplicates.contains(uri)));
+ for (String fid : bundle2featureId.get(uri)) {
+ writer.write(String.format(" <feature>%s</feature>\n", fid));
+ }
+ writer.write(" </bundle>\n");
}
- });
- writer.write(" </duplicates>\n");
- writer.write(" <bundles>\n");
- for (String uri : bundle2featureId.keySet()) {
- writer.write(String.format(" <bundle uri=\"%s\" duplicate=\"%b\">\n", sanitize(uri), haveDuplicates.contains(uri)));
- for (String fid : bundle2featureId.get(uri)) {
- writer.write(String.format(" <feature>%s</feature>\n", fid));
- }
- writer.write(" </bundle>\n");
+ writer.write(" </bundles>\n");
+ writer.write("</report>\n");
}
- writer.write(" </bundles>\n");
writer.write("</consistency-report>\n");
} catch (IOException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
+ private interface ReportFlavor {
+ String name();
+ boolean include(Features repository);
+ boolean include(Feature feature);
+ }
+
+ private ReportFlavor all = new ReportFlavor() {
+ @Override
+ public String name() {
+ return "all";
+ }
+
+ @Override
+ public boolean include(Features repository) {
+ return true;
+ }
+
+ @Override
+ public boolean include(Feature feature) {
+ return true;
+ }
+ };
+
+ private ReportFlavor notBlacklisted = new ReportFlavor() {
+ @Override
+ public String name() {
+ return "available";
+ }
+
+ @Override
+ public boolean include(Features repository) {
+ return !repository.isBlacklisted();
+ }
+
+ @Override
+ public boolean include(Feature feature) {
+ return !feature.isBlacklisted();
+ }
+ };
+
/**
* Sanitize before putting to XML
* @param uri
diff --git a/profile/src/main/resources/bundle-report.xslt b/profile/src/main/resources/bundle-report.xslt
index b4c21d5..0c43977 100644
--- a/profile/src/main/resources/bundle-report.xslt
+++ b/profile/src/main/resources/bundle-report.xslt
@@ -24,66 +24,167 @@
<html>
<head>
<meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous" />
- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous" />
-
<style type="text/css">
body { position: relative }
- h1 { margin: 2em 0 0.5em 0 }
+ li.active a { background-color: #eee }
div.bundle { padding: 5px; margin: 5px 0 }
+ #n { padding: 5px 15px }
+ #n a { padding: 5px 15px; margin: 0 5px }
</style>
- <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
- <script>
- $(function() {
- var hidden = true;
- $("#toggle").click(function(ev) {
- if (hidden) {
- $(".feature").show();
- hidden = false;
- $("#toggle").prop('value', 'Hide details');
- } else {
- $(".feature").hide();
- hidden = true;
- $("#toggle").prop('value', 'Show details');
- }
- });
- });
- </script>
</head>
- <body data-spy="scroll" data-target="#n">
- <div id="n">
- <nav id="nav" class="navbar navbar-inverse navbar-fixed-top" role="navigation">
- <div class="container">
- <div class="navbar-collapse collapse">
- <ul class="nav navbar-nav" role="tablist">
- <li class="active">
- <a href="#duplicates">Bundle <em>Duplicates</em> (<xsl:value-of select="count(/k:consistency-report/k:duplicates/k:duplicate)" />)</a>
+ <body data-spy="scroll" data-target="#n" data-offset="5">
+ <div class="container-fluid" style="position: fixed; z-index: 500; background-color: white; width: 100%; top: 0">
+ <div class="row">
+ <div class="col-lg-12">
+ <h3><xsl:value-of select="/k:consistency-report/@project" /><xsl:value-of select="' '" /><xsl:value-of select="/k:consistency-report/@version" /> consistency report</h3>
+ </div>
+ </div>
+ <div class="row">
+ <div class="col-lg-12">
+ <div class="container-fluid">
+ <ul class="nav nav-tabs" role="tablist">
+ <li id="installed" class="active">
+ <a role="tab" data-toggle="tab" href="#r1" data-t1="#t1b,#t1c,#t3,#t4" data-t2="#t1a,#t2">Installed features only</a>
</li>
<li>
- <a href="#bundles">All bundles (<xsl:value-of select="count(/k:consistency-report/k:bundles/k:bundle)" />)</a>
+ <a role="tab" data-toggle="tab" href="#r2" data-t1="#t1a,#t1c,#t2,#t4" data-t2="#t1b,#t3">Available features</a>
</li>
- <li style="min-height: 50px">
- <input id="toggle" class="btn btn-default" style="margin-top: 8px" type="button" value="Show details" />
+ <li>
+ <a role="tab" data-toggle="tab" href="#r3" data-t1="#t1a,#t1b,#t2,#t3" data-t2="#t1c,#t4">All features (including blacklisted)</a>
</li>
</ul>
</div>
</div>
- </nav>
+ </div>
+ <div class="row">
+ <div class="col-lg-12">
+ <div class="collapse navbar-collapse" id="n">
+ <ul class="nav navbar-nav">
+ <li class="nav-item active" id="t1a">
+ <a class="nav-link" href="#d0">
+ Bundle <em>Duplicates</em> (<xsl:value-of select="count(/k:consistency-report/k:report[@flavor='installed']/k:duplicates/k:duplicate)" />)
+ </a>
+ </li>
+ <li class="nav-item" id="t1b" style="display: none">
+ <a class="nav-link" href="#d0">
+ Bundle <em>Duplicates</em> (<xsl:value-of select="count(/k:consistency-report/k:report[@flavor='available']/k:duplicates/k:duplicate)" />)
+ </a>
+ </li>
+ <li class="nav-item" id="t1c" style="display: none">
+ <a class="nav-link" href="#d0">
+ Bundle <em>Duplicates</em> (<xsl:value-of select="count(/k:consistency-report/k:report[@flavor='all']/k:duplicates/k:duplicate)" />)
+ </a>
+ </li>
+ <li class="nav-item" id="t2">
+ <a class="nav-link" href="#d1">
+ All bundles (<xsl:value-of select="count(/k:consistency-report/k:report[@flavor='installed']/k:bundles/k:bundle)" />)
+ </a>
+ </li>
+ <li class="nav-item" id="t3" style="display: none">
+ <a class="nav-link" href="#d2">
+ All bundles (<xsl:value-of select="count(/k:consistency-report/k:report[@flavor='available']/k:bundles/k:bundle)" />)
+ </a>
+ </li>
+ <li class="nav-item" id="t4" style="display: none">
+ <a class="nav-link" href="#d3">
+ All bundles (<xsl:value-of select="count(/k:consistency-report/k:report[@flavor='all']/k:bundles/k:bundle)" />)
+ </a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ </div>
</div>
+ <div id="d0" style="height: 150px">a</div>
- <div class="container-fluid">
- <a id="duplicates" />
- <h1>Bundle <em>Duplicates</em></h1>
- <div class="help">(A <em>duplicate bundle</em> is a bundle that is referenced multiple times
- with the same Maven <code>groupId</code> and <code>artifactId</code> but with different versions.
- For each bundle that is used with different version, there's a list of all these versions and
- features (and their repositories) which include them.)</div>
- <xsl:apply-templates select="/k:consistency-report/k:duplicates" />
- <a id="bundles" />
- <h1>All bundles</h1>
- <xsl:call-template name="bundles" />
+ <div id="report" class="container-fluid" style="z-index: -1">
+ <div class="row">
+ <div class="tab-content col-lg-12">
+ <div id="r1" class="tab-pane active">
+ <div class="container-fluid">
+ <h4>All features that are actually installed in <code>etc/org.apache.karaf.features.cfg</code>.</h4>
+ <div>
+ <h1>Bundle <em>Duplicates</em></h1>
+ <div class="help">(A <em>duplicate bundle</em> is a bundle that is referenced multiple times
+ with the same Maven <code>groupId</code> and <code>artifactId</code> but with different versions.
+ For each bundle that is used with different version, there's a list of all these versions and
+ features (and their repositories) which include them.)</div>
+ <xsl:apply-templates select="/k:consistency-report/k:report[@flavor='installed']/k:duplicates" />
+ </div>
+ <div style="position: relative; margin-top: -150px">
+ <div id="d1" style="position: relative; top: 0; height: 150px"></div>
+ <div>
+ <h1>All bundles</h1>
+ <xsl:call-template name="bundles">
+ <xsl:with-param name="f" select="'installed'" />
+ </xsl:call-template>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="r2" class="tab-pane">
+ <div class="container-fluid">
+ <h4>All non-blacklisted features availalable to install, referenced from non-blacklisted repositories.</h4>
+ <div>
+ <h1>Bundle <em>Duplicates</em></h1>
+ <div class="help">(A <em>duplicate bundle</em> is a bundle that is referenced multiple times
+ with the same Maven <code>groupId</code> and <code>artifactId</code> but with different versions.
+ For each bundle that is used with different version, there's a list of all these versions and
+ features (and their repositories) which include them.)</div>
+ <xsl:apply-templates select="/k:consistency-report/k:report[@flavor='available']/k:duplicates" />
+ </div>
+ <div style="position: relative; margin-top: -150px">
+ <div id="d2" style="position: relative; top: 0; height: 150px"></div>
+ <div>
+ <h1>All bundles</h1>
+ <xsl:call-template name="bundles">
+ <xsl:with-param name="f" select="'available'" />
+ </xsl:call-template>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="r3" class="tab-pane">
+ <div class="container-fluid">
+ <h4>All features, including blacklisted ones.</h4>
+ <div>
+ <h1>Bundle <em>Duplicates</em></h1>
+ <div class="help">(A <em>duplicate bundle</em> is a bundle that is referenced multiple times
+ with the same Maven <code>groupId</code> and <code>artifactId</code> but with different versions.
+ For each bundle that is used with different version, there's a list of all these versions and
+ features (and their repositories) which include them.)</div>
+ <xsl:apply-templates select="/k:consistency-report/k:report[@flavor='all']/k:duplicates" />
+ </div>
+ <div style="position: relative; margin-top: -150px">
+ <div id="d3" style="position: relative; top: 0; height: 150px"></div>
+ <div>
+ <h1>All bundles</h1>
+ <xsl:call-template name="bundles">
+ <xsl:with-param name="f" select="'all'" />
+ </xsl:call-template>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
</div>
+
+ <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
+ <script>
+ $(function () {
+ $("#installed").addClass("active");
+ $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
+ $(window).scrollTop(0);
+ $($(e.target).data("t1")).hide();
+ $($(e.target).data("t2")).show();
+ $("body").scrollspy("refresh");
+ })
+ });
+ </script>
</body>
</html>
</xsl:template>
@@ -91,7 +192,7 @@
<xsl:template match="k:duplicate">
<div class="bundle">
<strong class="text-danger"><xsl:value-of select="@ga" /></strong>
- <ul class="feature" style="display: none">
+ <ul class="feature" style="display: block">
<xsl:for-each select="k:bundle">
<li>
<strong class="text-primary"><xsl:value-of select="@uri" /></strong>
@@ -107,6 +208,7 @@
</xsl:template>
<xsl:template name="bundles">
+ <xsl:param name="f" />
<table class="table table-condensed" style="table-layout: fixed">
<col width="30%" />
<col width="70%" />
@@ -117,7 +219,7 @@
</tr>
</thead>
<tbody>
- <xsl:for-each select="/k:consistency-report/k:bundles/k:bundle">
+ <xsl:for-each select="/k:consistency-report/k:report[@flavor=$f]/k:bundles/k:bundle">
<xsl:element name="tr">
<xsl:attribute name="class">
<xsl:if test="@duplicate='true'">danger</xsl:if>
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/AssemblyMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/AssemblyMojo.java
index 254d993..427daf9 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/AssemblyMojo.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/AssemblyMojo.java
@@ -276,6 +276,18 @@ public class AssemblyMojo extends MojoSupport {
@Parameter
private String generateConsistencyReport;
+ /**
+ * When generating consistency report, we can specify project name. By default it's "Apache Karaf"
+ */
+ @Parameter(defaultValue = "Apache Karaf")
+ private String consistencyReportProjectName;
+
+ /**
+ * When generating consistency report, we can specify project version. By default it's "${project.version}"
+ */
+ @Parameter(defaultValue = "${project.version}")
+ private String consistencyReportProjectVersion;
+
/*
* KARs are not configured using Maven plugin configuration, but rather detected from dependencies.
* All KARs are just unzipped into the assembly being constructed, but additionally KAR's embedded
@@ -475,6 +487,8 @@ public class AssemblyMojo extends MojoSupport {
builder.pidsToExtract(pidsToExtract);
builder.writeProfiles(writeProfiles);
builder.generateConsistencyReport(generateConsistencyReport);
+ builder.setConsistencyReportProjectName(consistencyReportProjectName);
+ builder.setConsistencyReportProjectVersion(consistencyReportProjectVersion);
builder.environment(environment);
builder.defaultStartLevel(defaultStartLevel);
if (featuresProcessing != null) {