Skip to content

Commit

Permalink
Adding Fliptables dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasbjerre committed Sep 12, 2018
1 parent 9714443 commit 70ef7b2
Show file tree
Hide file tree
Showing 5 changed files with 421 additions and 1 deletion.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ apply from: project.buildscript.classLoader.getResource('release.gradle').toURI(


dependencies {
compile 'se.bjurr.violations:violations-lib:1.54'
compile 'se.bjurr.violations:violations-lib:1.61'
compile 'org.eclipse.jgit:org.eclipse.jgit:4.9.2.201712150930-r'
compile 'com.jakewharton.fliptables:fliptables:1.0.2'

testCompile 'junit:junit:4.12'
testCompile 'org.assertj:assertj-core:2.3.0'
Expand Down
258 changes: 258 additions & 0 deletions src/main/java/se/bjurr/violations/git/ViolationsReporterApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
package se.bjurr.violations.git;

import static se.bjurr.violations.git.ViolationsReporterDetailLevel.COMPACT;
import static se.bjurr.violations.git.ViolationsReporterDetailLevel.PER_FILE_COMPACT;
import static se.bjurr.violations.git.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 com.jakewharton.fliptables.FlipTable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
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;

public class ViolationsReporterApi {

private Iterable<Violation> violations;
private int maxReporterColumnWidth;
private int maxRuleColumnWidth = 10;
private int maxSeverityColumnWidth;
private int maxLineColumnWidth;
private int maxMessageColumnWidth = 50;

private ViolationsReporterApi() {}

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

public String getReport(final ViolationsReporterDetailLevel level) {
checkNotNull(violations, "violations");

final StringBuilder sb = new StringBuilder();

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"));
}

return sb.toString();
}

private StringBuilder toVerbose(final Iterable<Violation> violations) {
final StringBuilder sb = new StringBuilder();
final Map<String, Set<Violation>> perFile = getViolationsPerFile(violations);
for (final Entry<String, Set<Violation>> perFileEntry : perFile.entrySet()) {
final String file = perFileEntry.getKey();
final Set<Violation> fileViolations = perFile.get(file);
sb.append(file + "\n");
sb.append(toDetailed(fileViolations, "Summary of " + file));
sb.append("\n");
}
return sb;
}

private StringBuilder toPerFile(final Iterable<Violation> violations) {
final StringBuilder sb = new StringBuilder();
final Map<String, Set<Violation>> perFile = getViolationsPerFile(violations);
for (final Entry<String, Set<Violation>> fileEntry : perFile.entrySet()) {
final Set<Violation> fileViolations = fileEntry.getValue();
final String fileName = fileEntry.getKey();
sb.append(toCompact(fileViolations, "Summary of " + fileName));
sb.append("\n");
}
return sb;
}

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

/**
* Avoid wider column. Will add new lines if wider. A value of 0 or less will disable the feature.
*/
public ViolationsReporterApi withMaxMessageColumnWidth(final int maxMessageColumnWidth) {
this.maxMessageColumnWidth = maxMessageColumnWidth;
return this;
}

/**
* Avoid wider column. Will add new lines if wider. A value of 0 or less will disable the feature.
*/
public ViolationsReporterApi withMaxLineColumnWidth(final int maxLineColumnWidth) {
this.maxLineColumnWidth = maxLineColumnWidth;
return this;
}

/**
* Avoid wider column. Will add new lines if wider. A value of 0 or less will disable the feature.
*/
public ViolationsReporterApi withMaxReporterColumnWidth(final int maxReporterColumnWidth) {
this.maxReporterColumnWidth = maxReporterColumnWidth;
return this;
}

/**
* Avoid wider column. Will add new lines if wider. A value of 0 or less will disable the feature.
*/
public ViolationsReporterApi withMaxRuleColumnWidth(final int maxRuleColumnWidth) {
this.maxRuleColumnWidth = maxRuleColumnWidth;
return this;
}

/** Avoid wider column. Will add new lines if wider. */
public ViolationsReporterApi withMaxSeverityColumnWidth(final int maxSeverityColumnWidth) {
this.maxSeverityColumnWidth = maxSeverityColumnWidth;
return this;
}

private StringBuilder toDetailed(
final Iterable<Violation> violations, final String summarySubject) {
final StringBuilder sb = new StringBuilder();
final List<String[]> rows = new ArrayList<>();
for (final Violation violation : violations) {
final String message = addNewlines(violation.getMessage(), maxMessageColumnWidth);
final String line = addNewlines(violation.getStartLine().toString(), maxLineColumnWidth);
final String severity = addNewlines(violation.getSeverity().name(), maxSeverityColumnWidth);
final String rule = addNewlines(violation.getRule(), maxRuleColumnWidth);
final String reporter = addNewlines(violation.getReporter(), maxReporterColumnWidth);
final String[] row = {reporter, rule, severity, line, message};
rows.add(row);
}

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;
}

private String addNewlines(final String message, final int maxLineLength) {
if (message == null) {
return "";
}
if (maxLineLength <= 0) {
return message;
}

int noLineCounter = 0;
final StringBuilder withNewlines = new StringBuilder();
for (int i = 0; i < message.length(); i++) {
final char charAt = message.charAt(i);
withNewlines.append(charAt);
if (charAt == '\n') {
noLineCounter = 0;
} else {
noLineCounter++;
}
if (noLineCounter > 0 && noLineCounter % maxLineLength == 0) {
withNewlines.append('\n');
noLineCounter = 0;
}
}
return withNewlines.toString().trim();
}

private StringBuilder toCompact(final Iterable<Violation> violations, final 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 Entry<String, Set<Violation>> reporterEntry : perReporter.entrySet()) {
final String reporter = reporterEntry.getKey();
final Set<Violation> reporterViolations = reporterEntry.getValue();
final Map<SEVERITY, Set<Violation>> perSeverity =
getViolationsPerSeverity(reporterViolations);
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 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(final Set<Violation> violations) {
final Map<SEVERITY, Set<Violation>> violationsPerSeverity = new TreeMap<>();
for (final SEVERITY severity : SEVERITY.values()) {
violationsPerSeverity.put(severity, new TreeSet<Violation>());
}

for (final Violation violation : violations) {
final Set<Violation> perReporter =
getOrCreate(violationsPerSeverity, violation.getSeverity());
perReporter.add(violation);
}
return violationsPerSeverity;
}

private Map<String, Set<Violation>> getViolationsPerFile(final 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(
final 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(final Map<K, Set<T>> container, final 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.git;

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 70ef7b2

Please sign in to comment.