File: formattedOutput.go

package info (click to toggle)
golang-github-zmap-zlint 3.6.2-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,008 kB
  • sloc: sh: 162; makefile: 38
file content (158 lines) | stat: -rw-r--r-- 4,152 bytes parent folder | download
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(" ")
			}
		}
	}

}