Skip to content

Commit

Permalink
Add support for different output formats and add codeclimate as an ou…
Browse files Browse the repository at this point in the history
…tput format

Co-authored-by: Stuart Reilly <s.reilly@intrallect.com>
  • Loading branch information
themadprofessor and Stuart Reilly committed Feb 12, 2024
1 parent 2b56d87 commit 641fed6
Show file tree
Hide file tree
Showing 9 changed files with 482 additions and 23 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,21 @@ documents all of these. The most commonly used flags:
* `-Dmodernizer.failOnViolations` - fail phase if violations detected, defaults to true
* `-Dmodernizer.skip` - skip plugin execution, defaults to false

### Output Formats

The plugin can output Modernizer violations in one of many formats which can be configured with the `<configuration>`
stanza using `<outputFormat>`.

The currently supported formats and their respective configuration options are outlined below:
* `CONSOLE` List each violation using Maven's logger. This is the **default** format.
* `<violationLogLevel>` Specify the log level of the logger: `error`, `warn`, `info` or `debug`.
Default is `error`.
* `CODE_CLIMATE` Write the violations according to [Code Climate's Spec](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md).
GitLab uses this format for its code quality as shown [here](https://docs.gitlab.com/ee/ci/testing/code_quality.html#implement-a-custom-tool).
* `<outputFile>` The full path the file to output to. Default is `${project.build.directory}/code-quality.json`
* `<codeClimateSeverity>` Severity of Modernizer violations for CodeClimate: `INFO`, `MINOR`, `MAJOR`, `CRITICAL` or `BLOCKER`.
Default is `MINOR`.

Ignoring elements
-----------------

Expand Down
5 changes: 5 additions & 0 deletions modernizer-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@
<artifactId>plexus-utils</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
Expand All @@ -41,6 +43,11 @@
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.gaul.modernizer_maven_plugin.output.CodeClimateOutputer;
import org.gaul.modernizer_maven_plugin.output.LoggerOutputer;
import org.gaul.modernizer_maven_plugin.output.OutputEntry;
import org.gaul.modernizer_maven_plugin.output.OutputFormat;
import org.gaul.modernizer_maven_plugin.output.Outputer;
import org.xml.sax.SAXException;

@Mojo(name = "modernizer", defaultPhase = LifecyclePhase.PROCESS_TEST_CLASSES,
Expand Down Expand Up @@ -121,8 +128,30 @@ public final class ModernizerMojo extends AbstractMojo {
@Parameter(property = "modernizer.exclusionsFile")
private String exclusionsFile;

/**
* Format to output violations in.
*/
@Parameter(defaultValue = "CONSOLE", property = "modernizer.outputFormat")
private OutputFormat outputFormat;

/**
* Path to the file to output violations to.
* Ignored if {@code modernizer.outputFormat} is {@code CONSOLE}.
*/
@Parameter(property = "modernizer.outputFile")
private String outputFile;

/**
* Severity of modernizer violations for CodeClimate.
* Ignored if {@code modernizer.outputFormat} is not {@code CODECLIMATE}.
*/
@Parameter(defaultValue = "MINOR",
property = "modernizer.codeclimateSeverity")
private CodeClimateOutputer.Severity codeClimateSeverity;

/**
* Log level to emit violations at, e.g., error, warn, info, debug.
* Ignored if {@code modernizer.outputFormat} is not {@code CONSOLE}.
*/
@Parameter(defaultValue = "error",
property = "modernizer.violationLogLevel")
Expand Down Expand Up @@ -181,6 +210,8 @@ public final class ModernizerMojo extends AbstractMojo {
@Parameter(defaultValue = "false", property = "modernizer.skip")
protected boolean skip = false;

private List<OutputEntry> outputEntries = new ArrayList<>();

@Override
public void execute() throws MojoExecutionException {
if (skip) {
Expand Down Expand Up @@ -268,18 +299,27 @@ public void execute() throws MojoExecutionException {
allExclusionPatterns, ignorePackages,
ignoreClassNames, allIgnoreFullClassNamePatterns);

long count;
try {
long count = recurseFiles(outputDirectory);
count = recurseFiles(outputDirectory);
if (includeTestClasses) {
count += recurseFiles(testOutputDirectory);
}
if (failOnViolations && count != 0) {
throw new MojoExecutionException("Found " + count +
" violations");
}
} catch (IOException ioe) {
throw new MojoExecutionException("Error reading Java classes", ioe);
}

try {
buildOutputer().output(outputEntries);
} catch (IOException ioe) {
throw new MojoExecutionException(
"Error outputting violations", ioe);
}

if (failOnViolations && count != 0) {
throw new MojoExecutionException("Found " + count +
" violations");
}
}

private static Map<String, Violation> parseViolations(
Expand Down Expand Up @@ -374,7 +414,7 @@ private long recurseFiles(File file) throws IOException {
name = name.substring(0,
name.length() - ".class".length()) + ".java";
}
emitViolation(name, occurrence);
outputEntries.add(new OutputEntry(name, occurrence));
++count;
}
} finally {
Expand All @@ -384,21 +424,16 @@ private long recurseFiles(File file) throws IOException {
return count;
}

private void emitViolation(String name, ViolationOccurrence occurrence) {
String message = name + ":" +
occurrence.getLineNumber() + ": " +
occurrence.getViolation().getComment();
if (violationLogLevel.equals("error")) {
getLog().error(message);
} else if (violationLogLevel.equals("warn")) {
getLog().warn(message);
} else if (violationLogLevel.equals("info")) {
getLog().info(message);
} else if (violationLogLevel.equals("debug")) {
getLog().debug(message);
} else {
throw new IllegalStateException("unexpected log level, was: " +
violationLogLevel);
private Outputer buildOutputer() throws MojoExecutionException {
String baseDir = project.getBuild().getDirectory();
if (Objects.requireNonNull(outputFormat) == OutputFormat.CONSOLE) {
return new LoggerOutputer(getLog(), violationLogLevel);
} else if (outputFormat == OutputFormat.CODE_CLIMATE) {
return new CodeClimateOutputer(
baseDir + "/" + CodeClimateOutputer.DEFAULT_FILENAME,
codeClimateSeverity);
}
throw new MojoExecutionException(
"Invalid output format: " + outputFormat);
}
}
Loading

0 comments on commit 641fed6

Please sign in to comment.