Skip to content

Commit

Permalink
Implementing reporter output
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasbjerre committed Dec 24, 2017
1 parent 593a3c0 commit e390aae
Show file tree
Hide file tree
Showing 39 changed files with 487 additions and 129 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@

Changelog of Violations lib.

## 1.44
### No issue

**Packaging fat jar as main jar**

* So that no special classifier is needed to get the relocated gson.

[764fe8fd94835a4](https://github.com/tomasbjerre/violations-lib/commit/764fe8fd94835a4) Tomas Bjerre *2017-12-22 18:28:23*


## 1.43
### No issue

Expand Down
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ apply from: project.buildscript.classLoader.getResource('release.gradle').toURI(

dependencies {
compile 'com.google.code.gson:gson:2.8.2'
compile 'com.jakewharton.fliptables:fliptables:1.0.2'
testCompile 'junit:junit:4.12'
testCompile 'org.assertj:assertj-core:2.3.0'
}

shadowJar {
relocate 'com.google', 'se.bjurr.com.google'
relocate 'com.google', project.group + '.com.google'
relocate 'com.jakewharton', project.group + '.com.jakewharton'
}
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version = 1.45-SNAPSHOT
version = 1.46-SNAPSHOT
13 changes: 13 additions & 0 deletions src/main/java/se/bjurr/violations/lib/DetailedReportCreator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package se.bjurr.violations.lib;

import java.util.List;
import se.bjurr.violations.lib.model.Violation;

class DetailedReportCreator {

DetailedReportCreator(List<Violation> violations) {}

String create() {
return null;
}
}
91 changes: 91 additions & 0 deletions src/main/java/se/bjurr/violations/lib/ViolationsApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package se.bjurr.violations.lib;

import static java.util.logging.Level.FINE;
import static se.bjurr.violations.lib.reports.ReportsFinder.findAllReports;
import static se.bjurr.violations.lib.util.Utils.checkNotNull;
import static se.bjurr.violations.lib.util.Utils.setReporter;

import java.io.File;
import java.util.List;
import java.util.logging.Logger;
import se.bjurr.violations.lib.model.Violation;
import se.bjurr.violations.lib.reports.Parser;

public class ViolationsApi {
private static Logger LOG = Logger.getLogger(ViolationsApi.class.getSimpleName());

private String pattern;
private Parser parser;
private File startFile;
private String reporter;

public static String getDetailedReport(List<Violation> violations) {
return new DetailedReportCreator(violations) //
.create();
}

public static ViolationsApi violationsApi() {
return new ViolationsApi();
}

private ViolationsApi() {}

public ViolationsApi findAll(Parser parser) {
this.parser = checkNotNull(parser, "parser");
return this;
}

public ViolationsApi withReporter(String reporter) {
this.reporter = checkNotNull(reporter, "reporter");
return this;
}

public ViolationsApi inFolder(String folder) {
startFile = new File(checkNotNull(folder, "folder"));
if (!startFile.exists()) {
throw new RuntimeException(folder + " not found");
}
return this;
}

public List<Violation> violations() {
final List<File> includedFiles = findAllReports(startFile, pattern);
if (LOG.isLoggable(FINE)) {
LOG.log(FINE, "Found " + includedFiles.size() + " reports:");
for (final File f : includedFiles) {
LOG.log(FINE, f.getAbsolutePath());
}
}
final List<Violation> foundViolations = parser.findViolations(includedFiles);
final boolean reporterWasSupplied =
reporter != null && !reporter.trim().isEmpty() && !reporter.equals(parser.name());
if (reporterWasSupplied) {
setReporter(foundViolations, reporter);
}

if (LOG.isLoggable(FINE)) {
LOG.log(FINE, "Found " + foundViolations.size() + " violations:");
for (final Violation v : foundViolations) {
LOG.log(
FINE,
v.getReporter()
+ " "
+ v.getSeverity()
+ " ("
+ v.getRule().or("?")
+ ") "
+ v.getFile()
+ " "
+ v.getStartLine()
+ " -> "
+ v.getEndLine());
}
}
return foundViolations;
}

public ViolationsApi withPattern(String regularExpression) {
pattern = regularExpression;
return this;
}
}
203 changes: 148 additions & 55 deletions src/main/java/se/bjurr/violations/lib/ViolationsReporterApi.java
Original file line number Diff line number Diff line change
@@ -1,88 +1,181 @@
package se.bjurr.violations.lib;

import static java.util.logging.Level.FINE;
import static se.bjurr.violations.lib.reports.ReportsFinder.findAllReports;
import static se.bjurr.violations.lib.ViolationsReporterDetailLevel.COMPACT;
import static se.bjurr.violations.lib.ViolationsReporterDetailLevel.PER_FILE_COMPACT;
import static se.bjurr.violations.lib.ViolationsReporterDetailLevel.VERBOSE;
import static se.bjurr.violations.lib.model.SEVERITY.ERROR;
import static se.bjurr.violations.lib.model.SEVERITY.INFO;
import static se.bjurr.violations.lib.model.SEVERITY.WARN;
import static se.bjurr.violations.lib.util.Utils.checkNotNull;
import static se.bjurr.violations.lib.util.Utils.setReporter;

import java.io.File;
import com.jakewharton.fliptables.FlipTable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import se.bjurr.violations.lib.model.SEVERITY;
import se.bjurr.violations.lib.model.Violation;
import se.bjurr.violations.lib.reports.Parser;

public class ViolationsReporterApi {
private static Logger LOG = Logger.getLogger(ViolationsReporterApi.class.getSimpleName());

private Iterable<Violation> violations;

private ViolationsReporterApi() {}

public static ViolationsReporterApi violationsReporterApi() {
return new ViolationsReporterApi();
}

private String pattern;
private Parser parser;
public String getReport(ViolationsReporterDetailLevel level) {
checkNotNull(violations, "violations");

private File startFile;
final StringBuilder sb = new StringBuilder();

private String reporter;
if (level == COMPACT) {
sb.append(toCompact(violations, "Summary"));
} else if (level == PER_FILE_COMPACT) {
sb.append(toPerFile(violations));
sb.append(toCompact(violations, "Summary"));
} else if (level == VERBOSE) {
sb.append(toVerbose(violations));
sb.append(toCompact(violations, "Summary"));
}

private ViolationsReporterApi() {}
return sb.toString();
}

public ViolationsReporterApi findAll(Parser parser) {
this.parser = checkNotNull(parser, "parser");
return this;
private StringBuilder toVerbose(Iterable<Violation> violations) {
final StringBuilder sb = new StringBuilder();
final Map<String, Set<Violation>> perFile = getViolationsPerFile(violations);
for (final String file : perFile.keySet()) {
sb.append(file + "\n");
sb.append(toDetailed(perFile.get(file), "Summary of " + file));
sb.append("\n");
}
return sb;
}

public ViolationsReporterApi withReporter(String reporter) {
this.reporter = checkNotNull(reporter, "reporter");
private StringBuilder toPerFile(Iterable<Violation> violations) {
final StringBuilder sb = new StringBuilder();
final Map<String, Set<Violation>> perFile = getViolationsPerFile(violations);
for (final String file : perFile.keySet()) {
sb.append(toCompact(perFile.get(file), "Summary of " + file));
sb.append("\n");
}
return sb;
}

public ViolationsReporterApi withViolations(List<Violation> violations) {
this.violations = violations;
return this;
}

public ViolationsReporterApi inFolder(String folder) {
startFile = new File(checkNotNull(folder, "folder"));
if (!startFile.exists()) {
throw new RuntimeException(folder + " not found");
private StringBuilder toDetailed(Iterable<Violation> violations, String summarySubject) {
final StringBuilder sb = new StringBuilder();
final List<String[]> rows = new ArrayList<>();
for (final Violation violation : violations) {
final String[] row = {
violation.getReporter(),
violation.getRule().or(""),
violation.getSeverity().name(),
violation.getStartLine().toString(),
violation.getMessage()
};
rows.add(row);
}
return this;

final String[] headers = {"Reporter", "Rule", "Severity", "Line", "Message"};

final String[][] data = rows.toArray(new String[][] {});
sb.append(FlipTable.of(headers, data));
sb.append("\n");
sb.append(toCompact(violations, summarySubject));
sb.append("\n");
return sb;
}

public List<Violation> violations() {
final List<File> includedFiles = findAllReports(startFile, pattern);
if (LOG.isLoggable(FINE)) {
LOG.log(FINE, "Found " + includedFiles.size() + " reports:");
for (final File f : includedFiles) {
LOG.log(FINE, f.getAbsolutePath());
}
private StringBuilder toCompact(Iterable<Violation> violations, String subject) {
final StringBuilder sb = new StringBuilder();
final Map<String, Set<Violation>> perReporter = getViolationsPerReporter(violations);
final List<String[]> rows = new ArrayList<>();

Integer totNumInfo = 0;
Integer totNumWarn = 0;
Integer totNumError = 0;
Integer totNumTot = 0;

for (final String reporter : perReporter.keySet()) {
final Map<SEVERITY, Set<Violation>> perSeverity =
getViolationsPerSeverity(perReporter.get(reporter));
final Integer numInfo = perSeverity.get(INFO).size();
final Integer numWarn = perSeverity.get(WARN).size();
final Integer numError = perSeverity.get(ERROR).size();
final Integer numTot = numInfo + numWarn + numError;
final String[] row = {
reporter, numInfo.toString(), numWarn.toString(), numError.toString(), numTot.toString()
};
rows.add(row);

totNumInfo += numInfo;
totNumWarn += numWarn;
totNumError += numError;
totNumTot += numTot;
}
final List<Violation> foundViolations = parser.findViolations(includedFiles);
final boolean reporterWasSupplied =
reporter != null && !reporter.trim().isEmpty() && !reporter.equals(parser.name());
if (reporterWasSupplied) {
setReporter(foundViolations, reporter);
final String[] row = {
"", totNumInfo.toString(), totNumWarn.toString(), totNumError.toString(), totNumTot.toString()
};
rows.add(row);

final String[] headers = {"Reporter", INFO.name(), WARN.name(), ERROR.name(), "Total"};

final String[][] data = rows.toArray(new String[][] {});
sb.append(subject + "\n");
sb.append(FlipTable.of(headers, data));
return sb;
}

private Map<SEVERITY, Set<Violation>> getViolationsPerSeverity(Set<Violation> violations) {
final Map<SEVERITY, Set<Violation>> violationsPerSeverity = new TreeMap<>();
for (final SEVERITY severity : SEVERITY.values()) {
violationsPerSeverity.put(severity, new TreeSet<Violation>());
}

if (LOG.isLoggable(FINE)) {
LOG.log(FINE, "Found " + foundViolations.size() + " violations:");
for (final Violation v : foundViolations) {
LOG.log(
FINE,
v.getReporter()
+ " "
+ v.getSeverity()
+ " ("
+ v.getRule().or("?")
+ ") "
+ v.getFile()
+ " "
+ v.getStartLine()
+ " -> "
+ v.getEndLine());
}
for (final Violation violation : violations) {
final Set<Violation> perReporter =
getOrCreate(violationsPerSeverity, violation.getSeverity());
perReporter.add(violation);
}
return foundViolations;
return violationsPerSeverity;
}

public ViolationsReporterApi withPattern(String regularExpression) {
pattern = regularExpression;
return this;
private Map<String, Set<Violation>> getViolationsPerFile(Iterable<Violation> violations) {
final Map<String, Set<Violation>> violationsPerFile = new TreeMap<>();
for (final Violation violation : violations) {
final Set<Violation> perReporter = getOrCreate(violationsPerFile, violation.getFile());
perReporter.add(violation);
}
return violationsPerFile;
}

private Map<String, Set<Violation>> getViolationsPerReporter(Iterable<Violation> violations) {
final Map<String, Set<Violation>> violationsPerReporter = new TreeMap<>();
for (final Violation violation : violations) {
final Set<Violation> perReporter =
getOrCreate(violationsPerReporter, violation.getReporter());
perReporter.add(violation);
}
return violationsPerReporter;
}

private <T, K> Set<T> getOrCreate(Map<K, Set<T>> container, K key) {
if (container.containsKey(key)) {
return container.get(key);
} else {
final Set<T> violationList = new TreeSet<>();
container.put(key, violationList);
return violationList;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package se.bjurr.violations.lib;

public enum ViolationsReporterDetailLevel {
/** Show detailed violations per file. */
VERBOSE,
/** Show number of violations. Per reporter and in total. */
COMPACT,
/** Like compact but per file. */
PER_FILE_COMPACT
}
Loading

0 comments on commit e390aae

Please sign in to comment.