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  }