Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for stats-output-file in maven-plugin #908

Merged
merged 5 commits into from
Oct 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions sorald/src/main/java/sorald/cli/BaseCommand.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
package sorald.cli;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.configurator.BasicComponentConfigurator;
import org.codehaus.plexus.component.configurator.ComponentConfigurator;
import org.codehaus.plexus.component.configurator.converters.basic.AbstractBasicConverter;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import picocli.CommandLine;
import sorald.Constants;

Expand All @@ -11,21 +21,67 @@
abstract class BaseCommand extends AbstractMojo implements Callable<Integer> {
@CommandLine.Spec CommandLine.Model.CommandSpec spec;

List<String> mavenArgs;

@CommandLine.Option(
names = Constants.ARG_TARGET,
description =
"The target of this execution (ex. sorald/92d377). This will be included in the json report.")
String target;

@Parameter(property = "statsOutputFile")
@CommandLine.Option(
names = Constants.ARG_STATS_OUTPUT_FILE,
description =
"Path to a file to store execution statistics in (in JSON format). If left unspecified, Sorald does not gather statistics.")
File statsOutputFile;

static class FileConverterForMojo extends AbstractBasicConverter {
@Override
protected Object fromString(String userInput) {
return new File(userInput);
algomaster99 marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
public boolean canConvert(Class<?> aClass) {
return aClass.equals(File.class);
}
}

@CommandLine.Option(
names = Constants.ARG_RESOLVE_CLASSPATH_FROM,
description =
"Path to the root of a project to resolve the classpath from. Currently only works for Maven projects.")
File resolveClasspathFrom;

/**
* This method is used to capture the arguments passed to maven-plugin to display them in the
* report.
*
* @return the list of arguments passed to the maven-plugin
*/
protected List<String> getMavenArgs() {
String[] rawCommand = System.getProperty("sun.java.command").split(" ");
algomaster99 marked this conversation as resolved.
Show resolved Hide resolved
String[] requiredParameters = Arrays.copyOfRange(rawCommand, 1, rawCommand.length);
List<String> args = new ArrayList<>();
args.add("mvn");
Collections.addAll(args, requiredParameters);
return args;
}
}

/**
* Looks for children of {@link AbstractBasicConverter} and registers them. These converters ensure
* type of value of {@link Parameter} is correctly converted to the type of the field as the parsed
* type is always {@link String}.
*/
@Component(role = ComponentConfigurator.class, hint = "basic")
class MojoParametersCheckerAndConverter extends BasicComponentConfigurator
implements Initializable {

@Override
public void initialize() {
converterLookup.registerConverter(new BaseCommand.FileConverterForMojo());
converterLookup.registerConverter(new RepairCommand.RulesConverterForMojo());
}
}
13 changes: 12 additions & 1 deletion sorald/src/main/java/sorald/cli/MineCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,21 @@ public Integer call() throws Exception {
}

if (statsOutputFile != null) {
List<String> originalArgs;
// If the plugin is used, the original arguments are stored in the mojo descriptor
if (mavenArgs != null) {
originalArgs = mavenArgs;
}
// If the CLI is used, the original arguments are stored in the command line spec of
// PicoCLI
else {
originalArgs = spec.commandLine().getParseResult().originalArgs();
}
Map<String, Object> additionalStatData =
Map.of(
StatsMetadataKeys.EXECUTION_INFO,
new ExecutionInfo(
spec.commandLine().getParseResult().originalArgs(),
originalArgs,
SoraldVersionProvider.getVersionFromPropertiesResource(
SoraldVersionProvider.DEFAULT_RESOURCE_NAME),
System.getProperty(Constants.JAVA_VERSION_SYSTEM_PROPERTY),
Expand Down Expand Up @@ -157,6 +167,7 @@ private void validateArgs() {

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
mavenArgs = getMavenArgs();
try {
call();
} catch (Exception e) {
Expand Down
27 changes: 12 additions & 15 deletions sorald/src/main/java/sorald/cli/RepairCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.configurator.BasicComponentConfigurator;
import org.codehaus.plexus.component.configurator.ComponentConfigurator;
import org.codehaus.plexus.component.configurator.converters.basic.AbstractBasicConverter;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import picocli.CommandLine;
import sorald.*;
import sorald.event.EventHelper;
Expand Down Expand Up @@ -56,6 +52,7 @@ class RepairCommand extends BaseCommand {

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
mavenArgs = getMavenArgs();
try {
call();
} catch (Exception e) {
Expand Down Expand Up @@ -235,9 +232,19 @@ private Set<RuleViolation> mineViolations(

private void writeStatisticsOutput(RepairStatisticsCollector statsCollector, Path projectPath)
throws IOException {
List<String> originalArgs;
// If the plugin is used, the original arguments are stored in the mojo descriptor
if (mavenArgs != null) {
originalArgs = mavenArgs;
}
// If the CLI is used, the original arguments are stored in the command line spec of
// PicoCLI
else {
originalArgs = spec.commandLine().getParseResult().originalArgs();
}
var executionInfo =
new ExecutionInfo(
spec.commandLine().getParseResult().originalArgs(),
originalArgs,
SoraldVersionProvider.getVersionFromPropertiesResource(
SoraldVersionProvider.DEFAULT_RESOURCE_NAME),
System.getProperty(Constants.JAVA_VERSION_SYSTEM_PROPERTY),
Expand Down Expand Up @@ -341,13 +348,3 @@ private SoraldConfig createConfig() {
return config;
}
}

/** Attaches itself to {@link RepairCommand} to convert `rules` field. */
@Component(role = ComponentConfigurator.class, hint = "basic")
class RulesMojoConfigurator extends BasicComponentConfigurator implements Initializable {

@Override
public void initialize() {
converterLookup.registerConverter(new RepairCommand.RulesConverterForMojo());
}
}
14 changes: 14 additions & 0 deletions sorald/src/test/java/sorald/it/MineMojoIT.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package sorald.it;

import static com.soebes.itf.extension.assertj.MavenITAssertions.assertThat;
import static org.hamcrest.io.FileMatchers.anExistingFile;

import com.soebes.itf.jupiter.extension.MavenGoal;
import com.soebes.itf.jupiter.extension.MavenJupiterExtension;
import com.soebes.itf.jupiter.extension.MavenOption;
import com.soebes.itf.jupiter.extension.MavenTest;
import com.soebes.itf.jupiter.maven.MavenExecutionResult;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -70,4 +72,16 @@ void handled_rules(MavenExecutionResult result) throws IOException {
.plain()
.contains(expectedOutput.toArray(new String[0]));
}

@MavenGoal("${project.groupId}:${project.artifactId}:${project.version}:mine")
@MavenOption("-DhandledRules")
@MavenOption("-DstatsOutputFile=stats.json")
@MavenTest
@DisplayName("Mine respects stats output file parameter and generates a JSON file")
void stats_output_file(MavenExecutionResult result) {
File projectRoot = result.getMavenProjectResult().getTargetProjectDirectory();
File statsOutputFile = new File(projectRoot, "stats.json");

org.hamcrest.MatcherAssert.assertThat(statsOutputFile, anExistingFile());
}
}
14 changes: 14 additions & 0 deletions sorald/src/test/java/sorald/it/RepairMojoIT.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package sorald.it;

import static com.soebes.itf.extension.assertj.MavenITAssertions.assertThat;
import static org.hamcrest.io.FileMatchers.anExistingFile;

import com.soebes.itf.jupiter.extension.MavenGoal;
import com.soebes.itf.jupiter.extension.MavenJupiterExtension;
import com.soebes.itf.jupiter.extension.MavenOption;
import com.soebes.itf.jupiter.extension.MavenTest;
import com.soebes.itf.jupiter.maven.MavenExecutionResult;
import java.io.File;
import org.junit.jupiter.api.DisplayName;

@MavenJupiterExtension
Expand Down Expand Up @@ -58,4 +60,16 @@ void perform_repairs(MavenExecutionResult result) {
"ToStringReturningNullProcessor: 1",
"-----End of report------");
}

@MavenGoal("${project.groupId}:${project.artifactId}:${project.version}:repair")
@MavenOption("-DruleKey=S2111")
@MavenOption("-DstatsOutputFile=stats.json")
@MavenTest
@DisplayName("Repair respects stats output file parameter and generates a JSON file")
void stats_output_file(MavenExecutionResult result) {
File projectRoot = result.getMavenProjectResult().getTargetProjectDirectory();
File statsOutputFile = new File(projectRoot, "stats.json");

org.hamcrest.MatcherAssert.assertThat(statsOutputFile, anExistingFile());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.foo.bar</groupId>
<artifactId>foobar</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>foobar</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
public class Main {
private int x = 42;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.foo.bar</groupId>
<artifactId>foobar</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>foobar</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import java.math.BigDecimal;

public class Main {
public static void main(String[] args) {
BigDecimal a = new BigDecimal(1.0);
System.out.println(a);
}
}