github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/syft/format/table/encoder.go (about)

     1  package table
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"sort"
     7  	"strings"
     8  
     9  	"github.com/olekukonko/tablewriter"
    10  
    11  	"github.com/anchore/syft/syft/sbom"
    12  )
    13  
    14  const ID sbom.FormatID = "syft-table"
    15  
    16  type encoder struct {
    17  }
    18  
    19  func NewFormatEncoder() sbom.FormatEncoder {
    20  	return encoder{}
    21  }
    22  
    23  func (e encoder) ID() sbom.FormatID {
    24  	return ID
    25  }
    26  
    27  func (e encoder) Aliases() []string {
    28  	return []string{
    29  		"table",
    30  	}
    31  }
    32  
    33  func (e encoder) Version() string {
    34  	return sbom.AnyVersion
    35  }
    36  
    37  func (e encoder) Encode(writer io.Writer, s sbom.SBOM) error {
    38  	var rows [][]string
    39  
    40  	columns := []string{"Name", "Version", "Type"}
    41  	for _, p := range s.Artifacts.Packages.Sorted() {
    42  		row := []string{
    43  			p.Name,
    44  			p.Version,
    45  			string(p.Type),
    46  		}
    47  		rows = append(rows, row)
    48  	}
    49  
    50  	if len(rows) == 0 {
    51  		_, err := fmt.Fprintln(writer, "No packages discovered")
    52  		return err
    53  	}
    54  
    55  	// sort by name, version, then type
    56  	sort.SliceStable(rows, func(i, j int) bool {
    57  		for col := 0; col < len(columns); col++ {
    58  			if rows[i][col] != rows[j][col] {
    59  				return rows[i][col] < rows[j][col]
    60  			}
    61  		}
    62  		return false
    63  	})
    64  	rows = removeDuplicateRows(rows)
    65  
    66  	table := tablewriter.NewWriter(writer)
    67  
    68  	table.SetHeader(columns)
    69  	table.SetHeaderLine(false)
    70  	table.SetBorder(false)
    71  	table.SetAutoWrapText(false)
    72  	table.SetAutoFormatHeaders(true)
    73  	table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
    74  	table.SetAlignment(tablewriter.ALIGN_LEFT)
    75  	table.SetCenterSeparator("")
    76  	table.SetColumnSeparator("")
    77  	table.SetRowSeparator("")
    78  	table.SetTablePadding("  ")
    79  	table.SetNoWhiteSpace(true)
    80  
    81  	table.AppendBulk(rows)
    82  	table.Render()
    83  
    84  	return nil
    85  }
    86  
    87  func removeDuplicateRows(items [][]string) [][]string {
    88  	seen := map[string][]string{}
    89  	var result [][]string
    90  
    91  	for _, v := range items {
    92  		key := strings.Join(v, "|")
    93  		if seen[key] != nil {
    94  			// dup!
    95  			continue
    96  		}
    97  
    98  		seen[key] = v
    99  		result = append(result, v)
   100  	}
   101  	return result
   102  }