Skip to content

Commit

Permalink
Add a :report goal to generate plugin executions list in HTML
Browse files Browse the repository at this point in the history
It will be added to Project Reports in Maven site.

Fixes #76
  • Loading branch information
jcgay committed Jul 31, 2022
1 parent 2f124e1 commit 86b2717
Show file tree
Hide file tree
Showing 10 changed files with 409 additions and 3 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@ It is possible to limit the list to a specific plugin:
### List to output file

mvn buildplan:list -Dbuildplan.outputFile=buildplan_output.txt

### Report plugin executions within a project

mvn buildplan:report
34 changes: 34 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
<mojo.java.target>1.8</mojo.java.target>
<project.build.outputTimestamp>2022-06-21T18:36:44Z</project.build.outputTimestamp>
<jacoco-maven-plugin.version>0.8.8</jacoco-maven-plugin.version>
<doxia.version>1.10</doxia.version>
<maven-reporting.version>3.1.0</maven-reporting.version>
<itf.version>0.11.0</itf.version>
</properties>

Expand Down Expand Up @@ -82,6 +84,12 @@
<version>${itf.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.15.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
Expand All @@ -93,11 +101,37 @@
<version>${project.prerequisites.maven}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>${project.prerequisites.maven}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.doxia</groupId>
<artifactId>doxia-sink-api</artifactId>
<version>${doxia.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.doxia</groupId>
<artifactId>doxia-site-renderer</artifactId>
<version>${doxia.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.reporting</groupId>
<artifactId>maven-reporting-impl</artifactId>
<version>${maven-reporting.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.reporting</groupId>
<artifactId>maven-reporting-api</artifactId>
<version>${maven-reporting.version}</version>
</dependency>
</dependencies>

<build>
Expand Down
157 changes: 157 additions & 0 deletions src/main/java/org/codehaus/mojo/buildplan/ListReportMojo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* Copyright (C) 2012 Jean-Christophe Gay ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.mojo.buildplan;


import static org.codehaus.mojo.buildplan.display.TableColumn.ARTIFACT_ID;
import static org.codehaus.mojo.buildplan.display.TableColumn.GOAL;
import static org.codehaus.mojo.buildplan.display.TableColumn.LIFECYCLE;
import static org.codehaus.mojo.buildplan.display.TableColumn.PHASE;

import java.util.Locale;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.DefaultLifecycles;
import org.apache.maven.lifecycle.LifecycleExecutor;
import org.apache.maven.lifecycle.MavenExecutionPlan;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.codehaus.mojo.buildplan.display.MojoExecutionDisplay;
import org.codehaus.mojo.buildplan.display.TableColumn;

/**
* Report plugin executions for the current project.
*/
@Mojo(name = "report",
defaultPhase = LifecyclePhase.SITE)
public class ListReportMojo extends AbstractMavenReport {

@Component
private LifecycleExecutor lifecycleExecutor;

@Component(role = DefaultLifecycles.class)
DefaultLifecycles defaultLifecycles;

@Parameter(defaultValue = "${session}", readonly = true)
private MavenSession session;

@Override
protected void executeReport(Locale locale) throws MavenReportException {

MavenExecutionPlan plan;
try {
plan = calculateExecutionPlan();
} catch (MojoFailureException e) {
throw new MavenReportException("Cannot calculate execution plan...", e);
}

Log logger = getLog();
logger.info("Generating " + getOutputName() + ".html"
+ " for " + project.getName() + " " + project.getVersion());

// Get the Maven Doxia Sink, which will be used to generate the
// various elements of the document
Sink mainSink = getSink();
if (mainSink == null) {
throw new MavenReportException("Could not get the Doxia sink");
}

// Page title
mainSink.head();
mainSink.title();
mainSink.text("Build Plan for " + project.getName() + " " + project.getVersion());
mainSink.title_();
mainSink.head_();

mainSink.body();

mainSink.header();
mainSink.rawText("<h1 id=\"titleContent\">" + getDescription(locale) + "</h1>");
mainSink.header_();

mainSink.table();

mainSink.tableRow();
tableHead(mainSink, LIFECYCLE);
tableHead(mainSink, PHASE);
tableHead(mainSink, ARTIFACT_ID);
tableHead(mainSink, GOAL);
tableHead(mainSink, ARTIFACT_ID);
mainSink.tableRow_();

for (MojoExecution execution : plan.getMojoExecutions()) {
MojoExecutionDisplay display = new MojoExecutionDisplay(execution);
mainSink.tableRow();
tableCell(mainSink, display.getLifecycle(defaultLifecycles));
tableCell(mainSink, display.getPhase());
tableCell(mainSink, display.getArtifactId());
tableCell(mainSink, display.getGoal());
tableCell(mainSink, display.getExecutionId());
mainSink.tableRow_();
}

mainSink.table_();

mainSink.body_();
}

private void tableCell(Sink mainSink, String content) {
mainSink.tableCell();
mainSink.text(content);
mainSink.tableCell_();
}

private void tableHead(Sink mainSink, TableColumn lifecycle) {
mainSink.tableHeaderCell();
mainSink.text(lifecycle.title());
mainSink.tableHeaderCell_();
}

@Override
public String getOutputName() {
return "buildplan-report";
}

@Override
public String getName(Locale locale) {
return "Build Plan";
}

@Override
public String getDescription(Locale locale) {
return "List plugin executions for " + currentProject();
}

private String currentProject() {
return session.getCurrentProject().getGroupId() + ":" + session.getCurrentProject()
.getArtifactId();
}

protected MavenExecutionPlan calculateExecutionPlan() throws MojoFailureException {
try {
return lifecycleExecutor.calculateExecutionPlan(session, "deploy");
} catch (Exception e) {
throw new MojoFailureException(String.format("Cannot calculate Maven execution plan, caused by: %s", e.getMessage()), e);
}
}
}
1 change: 1 addition & 0 deletions src/site/markdown/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The BuildPlan plugin has three goals:
* [buildplan:list](list-mojo.html) displays plugin executions within a Maven project.
* [buildplan:list-phase](list-phase-mojo.html) displays plugin executions within lifecycle phases.
* [buildplan:list-plugin](list-plugin-mojo.html) displays plugin executions by plugin.
* [buildplan:report](report-mojo.html) Creates a nicely formatted report in html format.

## Examples

Expand Down
37 changes: 34 additions & 3 deletions src/site/markdown/usage.md → src/site/markdown/usage.md.vm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Usage

## List plugin executions within a project
#[[##]]# List plugin executions within a project
```
> mvn buildplan:list

Expand Down Expand Up @@ -32,7 +32,7 @@ If you want to show the lifecycle that defines the listed phase(s), add this par

mvn buildplan:list-phase -Dbuildplan.showLifecycles

## List plugin executions within phases
#[[##]]# List plugin executions within phases
```
> mvn buildplan:list-phase

Expand Down Expand Up @@ -79,7 +79,7 @@ Here it is also possible to show the lifecycle(s) by running:
Be aware that setting `buildplan.tasks` to direct plugin-executions (eg 'release:prepare') will show an empty lifecycle and '&lt;no phase&gt;', since they are not mapped.
Also, because executions are collected per phase, direct plugin-executions are shown in the list at the location of the very first execution.

## List plugin executions by plugins
#[[##]]# List plugin executions by plugins
```
> mvn buildplan:list-plugin

Expand Down Expand Up @@ -117,3 +117,34 @@ It is possible to limit the list to a specific plugin:
It is possible to redirect the output to a file:

mvn buildplan:list-plugin -Dbuildplan.outputFile=buildplan_output.txt

#[[##]]# Generate the report as part of project reports

To generate the report as part of the site generation, add the following in the `<reporting>` section of your POM:

```
<project>
...
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildplan-maven-plugin</artifactId>
<version>${project.version}</version>
</plugin>
</plugins>
</reporting>
...
</project>
```

When `mvn site` is invoked, the report will automatically be
included in the Project Reports menu as shown in the figure below.

![buildplan report example](images/report-example.png "BuildPlan report example")

#[[##]]# Generate the report in a standalone fashion

mvn buildplan:report

A HTML report should be generated in `${basedir}/target/site/buildplan-report.html`.
Binary file added src/site/resources/images/report-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
92 changes: 92 additions & 0 deletions src/test/java/org/codehaus/mojo/buildplan/ListReportIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright (C) 2012 Jean-Christophe Gay ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.mojo.buildplan;

import static com.soebes.itf.extension.assertj.MavenITAssertions.assertThat;

import com.soebes.itf.jupiter.extension.MavenGoal;
import com.soebes.itf.jupiter.extension.MavenJupiterExtension;
import com.soebes.itf.jupiter.extension.MavenTest;
import com.soebes.itf.jupiter.maven.MavenExecutionResult;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

@MavenJupiterExtension
class ListReportIT {

@MavenTest
@MavenGoal("site")
void generate_report_for_multimodule_project(MavenExecutionResult result) {
assertThat(result).isSuccessful()
.project()
.withFile("site/buildplan-report.html")
.content()
.satisfies(html -> {
Document document = Jsoup.parse(html);
assertThat(document.title()).isEqualTo("list-multimodule – Build Plan for list-multimodule 1.0-SNAPSHOT");
assertThat(document.select("#titleContent").text()).isEqualTo("List plugin executions for org.codehaus.mojo.buildplan:list-multimodule");
assertThat(document.select("table.bodyTable").outerHtml()).isEqualTo("<table border=\"0\" class=\"bodyTable\">\n"
+ " <tbody>\n"
+ " <tr class=\"a\">\n"
+ " <th>LIFECYCLE</th>\n"
+ " <th>PHASE</th>\n"
+ " <th>PLUGIN</th>\n"
+ " <th>GOAL</th>\n"
+ " <th>PLUGIN</th>\n"
+ " </tr>\n"
+ " <tr class=\"b\">\n"
+ " <td>default</td>\n"
+ " <td>install</td>\n"
+ " <td>maven-install-plugin</td>\n"
+ " <td>install</td>\n"
+ " <td>default-install</td>\n"
+ " </tr>\n"
+ " <tr class=\"a\">\n"
+ " <td>default</td>\n"
+ " <td>deploy</td>\n"
+ " <td>maven-deploy-plugin</td>\n"
+ " <td>deploy</td>\n"
+ " <td>default-deploy</td>\n"
+ " </tr>\n"
+ " </tbody>\n"
+ "</table>");
});

assertThat(result)
.project()
.withModule("module-a")
.withFile("site/buildplan-report.html")
.content()
.satisfies(html -> {
Document document = Jsoup.parse(html);
assertThat(document.title()).isEqualTo("list-multimodule-module-a – Build Plan for list-multimodule-module-a 1.0-SNAPSHOT");
assertThat(document.select("#titleContent").text()).isEqualTo("List plugin executions for org.codehaus.mojo.buildplan:list-multimodule-module-a");
assertThat(document.select("table.bodyTable").outerHtml()).isNotEmpty();
});

assertThat(result)
.project()
.withModule("module-b")
.withFile("site/buildplan-report.html")
.content()
.satisfies(html -> {
Document document = Jsoup.parse(html);
assertThat(document.title()).isEqualTo("list-multimodule-module-b – Build Plan for list-multimodule-module-b 1.0-SNAPSHOT");
assertThat(document.select("#titleContent").text()).isEqualTo("List plugin executions for org.codehaus.mojo.buildplan:list-multimodule-module-b");
assertThat(document.select("table.bodyTable").outerHtml()).isNotEmpty();
});
}
}
Loading

0 comments on commit 86b2717

Please sign in to comment.