github.com/googleapis/api-linter@v1.65.2/cmd/api-linter/summary.go (about) 1 // Copyright 2019 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "bytes" 19 "fmt" 20 "sort" 21 22 "github.com/googleapis/api-linter/lint" 23 "github.com/olekukonko/tablewriter" 24 ) 25 26 // printSummaryTable returns a summary table of violation counts. 27 func printSummaryTable(responses []lint.Response) ([]byte, error) { 28 s := createSummary(responses) 29 30 data := []summary{} 31 for ruleID, fileViolations := range s { 32 totalViolations := 0 33 for _, count := range fileViolations { 34 totalViolations += count 35 } 36 data = append(data, summary{ruleID, totalViolations, len(fileViolations)}) 37 } 38 sort.SliceStable(data, func(i, j int) bool { return data[i].violations < data[j].violations }) 39 40 var buf bytes.Buffer 41 table := tablewriter.NewWriter(&buf) 42 table.SetHeader([]string{"Rule", "Total Violations", "Violated Files"}) 43 table.SetCaption(true, fmt.Sprintf("Linted %d proto files", len(responses))) 44 for _, d := range data { 45 table.Append([]string{ 46 d.ruleID, 47 fmt.Sprintf("%d", d.violations), 48 fmt.Sprintf("%d", d.files), 49 }) 50 } 51 table.Render() 52 53 return buf.Bytes(), nil 54 } 55 56 func createSummary(responses []lint.Response) map[string]map[string]int { 57 summary := make(map[string]map[string]int) 58 for _, r := range responses { 59 filePath := string(r.FilePath) 60 for _, p := range r.Problems { 61 ruleID := string(p.RuleID) 62 if summary[ruleID] == nil { 63 summary[ruleID] = make(map[string]int) 64 } 65 summary[ruleID][filePath]++ 66 } 67 } 68 return summary 69 } 70 71 type summary struct { 72 ruleID string 73 violations int 74 files int 75 }