github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/scanners/terraform/executor/statistics.go (about)

     1  package executor
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"sort"
     8  	"strconv"
     9  	"strings"
    10  
    11  	"github.com/khulnasoft-lab/defsec/pkg/scan"
    12  
    13  	"github.com/olekukonko/tablewriter"
    14  )
    15  
    16  type StatisticsItem struct {
    17  	RuleID          string   `json:"rule_id"`
    18  	RuleDescription string   `json:"rule_description"`
    19  	Links           []string `json:"links"`
    20  	Count           int      `json:"count"`
    21  }
    22  
    23  type Statistics []StatisticsItem
    24  
    25  type StatisticsResult struct {
    26  	Result Statistics `json:"results"`
    27  }
    28  
    29  func SortStatistics(statistics Statistics) Statistics {
    30  	sort.Slice(statistics, func(i, j int) bool {
    31  		return statistics[i].Count > statistics[j].Count
    32  	})
    33  	return statistics
    34  }
    35  
    36  func (statistics Statistics) PrintStatisticsTable(format string, w io.Writer) error {
    37  	// lovely is the default so we keep it like that
    38  	if format != "lovely" && format != "markdown" && format != "json" {
    39  		return fmt.Errorf("you must specify only lovely, markdown or json format with --run-statistics")
    40  	}
    41  
    42  	sorted := SortStatistics(statistics)
    43  
    44  	if format == "json" {
    45  		result := StatisticsResult{Result: sorted}
    46  		val, err := json.MarshalIndent(result, "", "    ")
    47  		if err != nil {
    48  			return err
    49  		}
    50  
    51  		_, _ = fmt.Fprintln(w, string(val))
    52  
    53  		return nil
    54  	}
    55  
    56  	table := tablewriter.NewWriter(w)
    57  	table.SetHeader([]string{"Rule ID", "Description", "Link", "Count"})
    58  	table.SetRowLine(true)
    59  
    60  	if format == "markdown" {
    61  		table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false})
    62  		table.SetCenterSeparator("|")
    63  	}
    64  
    65  	for _, item := range sorted {
    66  		table.Append([]string{item.RuleID,
    67  			item.RuleDescription,
    68  			strings.Join(item.Links, "\n"),
    69  			strconv.Itoa(item.Count)})
    70  	}
    71  
    72  	table.Render()
    73  
    74  	return nil
    75  }
    76  
    77  func AddStatisticsCount(statistics Statistics, result scan.Result) Statistics {
    78  	for i, statistic := range statistics {
    79  		if statistic.RuleID == result.Rule().LongID() {
    80  			statistics[i].Count += 1
    81  			return statistics
    82  		}
    83  	}
    84  	statistics = append(statistics, StatisticsItem{
    85  		RuleID:          result.Rule().LongID(),
    86  		RuleDescription: result.Rule().Summary,
    87  		Links:           result.Rule().Links,
    88  		Count:           1,
    89  	})
    90  
    91  	return statistics
    92  }