1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
package formattedoutput
import (
"fmt"
"sort"
"strconv"
"strings"
"unicode/utf8"
"github.com/zmap/zlint/v3"
"github.com/zmap/zlint/v3/lint"
)
type resultsTable struct {
resultCount map[lint.LintStatus]int
resultDetails map[lint.LintStatus][]string
lintLevelsAboveThreshold map[int]lint.LintStatus
sortedLevels []int
}
func (r *resultsTable) newRT(threshold lint.LintStatus, results *zlint.ResultSet, longSummary bool) resultsTable {
r.resultCount = make(map[lint.LintStatus]int)
r.resultDetails = make(map[lint.LintStatus][]string)
r.lintLevelsAboveThreshold = make(map[int]lint.LintStatus)
// Make the list of lint levels that matter
for _, i := range lint.StatusLabelToLintStatus {
if i <= threshold {
continue
}
r.lintLevelsAboveThreshold[int(i)] = i
}
// Set all of the levels to 0 events so they are all displayed
// in the -summary table
for _, level := range r.lintLevelsAboveThreshold {
r.resultCount[level] = 0
}
// Count up the number of each event
for lintName, lintResult := range results.Results {
if lintResult.Status > threshold {
r.resultCount[lintResult.Status]++
if longSummary {
r.resultDetails[lintResult.Status] = append(
r.resultDetails[lintResult.Status],
lintName,
)
}
}
}
// Sort the levels we have so we can get a nice output
for key := range r.resultCount {
r.sortedLevels = append(r.sortedLevels, int(key))
}
sort.Ints(r.sortedLevels)
return *r
}
func OutputSummary(zlintResult *zlint.ResultSet, longSummary bool) {
// Set the threashold under which (inclusive) events are not
// counted
threshold := lint.Pass
rt := (&resultsTable{}).newRT(threshold, zlintResult, longSummary)
// make and print the requested table type
if longSummary {
// make a table with the internal lint names grouped
// by type
var olsl string
headings := []string{
"Level",
"# occurrences",
" Details ",
}
lines := [][]string{}
var lsl string
var rescount string
hlengths := printTableHeadings(headings)
// Construct the table lines, but don't repeat
// LintStatus(level) or the results count. Also, just
// because a level wasn't seen doesn't mean it isn't
// important; display "empty" levels, too
for _, level := range rt.sortedLevels {
foundDetail := false
for _, detail := range rt.resultDetails[lint.LintStatus(level)] {
if lint.LintStatus(level).String() != olsl {
olsl = lint.LintStatus(level).String()
lsl = olsl
rescount = strconv.Itoa(rt.resultCount[lint.LintStatus(level)])
} else {
lsl = ""
rescount = ""
}
lines = append(lines, ([]string{lsl, rescount, detail}))
foundDetail = true
}
if !foundDetail {
lines = append(lines, []string{
lint.LintStatus(level).String(),
strconv.Itoa(rt.resultCount[lint.LintStatus(level)]),
" - ",
})
}
}
printTableBody(hlengths, lines)
} else {
headings := []string{"Level", "# occurrences"}
hlengths := printTableHeadings(headings)
lines := [][]string{}
for _, level := range rt.sortedLevels {
lines = append(lines, []string{
lint.LintStatus(level).String(),
strconv.Itoa(rt.resultCount[lint.LintStatus(level)])})
}
printTableBody(hlengths, lines)
fmt.Printf("\n")
}
}
func printTableHeadings(headings []string) []int {
hlengths := []int{}
for i, h := range headings {
hlengths = append(
hlengths,
utf8.RuneCountInString(h)+1)
fmt.Printf("| %s ", strings.ToUpper(h))
if i == len(headings)-1 {
fmt.Printf("|\n")
for ii, j := range hlengths {
fmt.Printf("+%s", strings.Repeat("-", j+1))
if ii == len(headings)-1 {
fmt.Printf("+\n")
}
}
}
}
return hlengths
}
func printTableBody(hlengths []int, lines [][]string) {
for _, line := range lines {
for i, hlen := range hlengths {
// This makes a format string with the
// right widths, e.g. "%7.7s"
fmtstring := fmt.Sprintf("|%%%[1]d.%[1]ds", hlen)
fmt.Printf(fmtstring, line[i])
if i == len(hlengths)-1 {
fmt.Printf(" |\n")
} else {
fmt.Printf(" ")
}
}
}
}
|