All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.itsallcode.openfasttrace.maven.TraceMojo Maven / Gradle / Ivy

package org.itsallcode.openfasttrace.maven;

import java.io.*;
import java.nio.file.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.*;
import org.apache.maven.project.*;
import org.itsallcode.openfasttrace.api.ReportSettings;
import org.itsallcode.openfasttrace.api.core.*;
import org.itsallcode.openfasttrace.api.importer.ImportSettings;
import org.itsallcode.openfasttrace.api.report.ReportVerbosity;
import org.itsallcode.openfasttrace.core.Oft;
import org.itsallcode.openfasttrace.core.OftRunner;

/**
 * Trace requirements using OpenFastTrace
 */
@Mojo(name = "trace", defaultPhase = LifecyclePhase.VERIFY)
public class TraceMojo extends AbstractMojo
{
    /**
     * Location of the directory where the reports are generated.
     * 

* Default: ${project.build.directory} */ @Parameter(defaultValue = "${project.build.directory}", property = "outputDirectory", required = true) private File outputDirectory; /** * Let build fail when tracing fails. *

* Default: true */ @Parameter(defaultValue = "true", property = "failBuild", required = true) private boolean failBuild; /** * The report output format, e.g. plain or html. *

* Default: html */ @Parameter(defaultValue = "html", property = "reportOutputFormat", required = true) private String reportOutputFormat; /** * The report verbosity *

    *
  • QUIET
  • *
  • MINIMAL
  • *
  • SUMMARY
  • *
  • FAILURES
  • *
  • FAILURE_SUMMARIES
  • *
  • FAILURE_DETAILS
  • *
  • ALL
  • *
*

* Default: FAILURE_DETAILS */ @Parameter(defaultValue = "FAILURE_DETAILS", property = "reportVerbosity", required = true) private ReportVerbosity reportVerbosity; /** * Show the origin in the tracing report. *

* Default: false */ @Parameter(defaultValue = "false", property = "reportShowOrigin", required = true) private boolean reportShowOrigin; @Parameter(defaultValue = "${project}", readonly = true) private MavenProject project; @Component private ProjectBuilder mavenProjectBuilder; @Parameter(defaultValue = "${session}", readonly = true) private MavenSession session; @Override public void execute() throws MojoFailureException { final Oft oft = new OftRunner(); getLog().info("Importing spec items..."); final List items = oft.importItems(createImportSettings()); getLog().info("Imported " + items.size() + " items."); final List linkedItems = oft.link(items); final Trace trace = oft.trace(linkedItems); writeTracingReport(oft, trace); if (trace.countDefects() == 0) { getLog().info("Tracing found no defects in " + trace.count() + " items"); return; } final String message = "Tracing found " + trace.countDefects() + " defects out of " + trace.count() + " items"; getLog().warn(message); logTracingReport(oft, trace); if (failBuild) { throw new MojoFailureException(message); } } private void logTracingReport(final Oft oft, final Trace trace) { final ReportSettings reportSettings = ReportSettings.builder() .outputFormat("plain") .verbosity(ReportVerbosity.FAILURE_DETAILS) .showOrigin(false) .build(); oft.reportToStdOut(trace, reportSettings); } private void writeTracingReport(final Oft oft, final Trace trace) { final Path outputPath = getOutputPath(); final ReportSettings reportSettings = ReportSettings.builder() .outputFormat(reportOutputFormat) .verbosity(reportVerbosity) .showOrigin(reportShowOrigin) .build(); getLog().info("Writing tracing report to " + outputPath + " using settings " + formatSettings(reportSettings)); oft.reportToPath(trace, outputPath, reportSettings); } private String formatSettings(ReportSettings reportSettings) { return "[output format: " + reportSettings.getOutputFormat() + ", verbosity: " + reportSettings.getReportVerbosity() + ", show origin: " + reportSettings.showOrigin() + ", newline: " + reportSettings.getNewline().name() + "]"; } private Path getOutputPath() { final String reportSuffix = "html".equals(reportOutputFormat) ? "html" : "txt"; final Path outputPath = outputDirectory.toPath().resolve("tracing-report." + reportSuffix); createDir(outputPath.getParent()); return outputPath; } private void createDir(final Path path) { if (path.toFile().exists()) { return; } try { Files.createDirectories(path); } catch (final IOException e) { throw new UncheckedIOException("Error creating directory " + path, e); } } private ImportSettings createImportSettings() { final ImportSettings.Builder settings = ImportSettings.builder() // .addInputs(getSourcePaths()); final Optional docPath = getProjectSubPath("doc"); if (docPath.isPresent()) { settings.addInputs(docPath.get()); } return settings.build(); } private List getSourcePaths() { return getSourcePathOfProject(this.project); } private Path getPomOfSubModule(String moduleName) { return this.project.getBasedir().toPath().resolve(moduleName).resolve("pom.xml"); } private MavenProject readProject(final Path pomFile) { try { final ProjectBuildingResult build = this.mavenProjectBuilder.build(pomFile.toFile(), this.session.getProjectBuildingRequest()); return build.getProject(); } catch (final ProjectBuildingException exception) { throw new IllegalStateException( "Failed to read sub module \"" + pomFile + "\".", exception); } } private List getSourcePathOfProject(MavenProject project) { final Stream sourcePathsOfSubModules = project.getModules().stream() .map(moduleName -> readProject(getPomOfSubModule(moduleName))) .flatMap(eachProject -> this.getSourcePathOfProject(eachProject).stream()); final Stream thisProjectsSourcePaths = Stream .concat(project.getCompileSourceRoots().stream(), project.getTestCompileSourceRoots().stream()) .map(Paths::get); return Stream.concat(sourcePathsOfSubModules, thisProjectsSourcePaths).collect(Collectors.toList()); } private Optional getProjectSubPath(String dir) { final File file = new File(project.getBasedir(), dir); return file.exists() ? Optional.of(file.toPath()) : Optional.empty(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy