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

     1  package spdxjson
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  
     8  	"github.com/spdx/tools-golang/convert"
     9  	"github.com/spdx/tools-golang/spdx/v2/v2_1"
    10  	"github.com/spdx/tools-golang/spdx/v2/v2_2"
    11  	"github.com/spdx/tools-golang/spdx/v2/v2_3"
    12  
    13  	"github.com/anchore/syft/syft/format/common/spdxhelpers"
    14  	"github.com/anchore/syft/syft/sbom"
    15  	"github.com/lineaje-labs/syft/syft/format/internal/spdxutil"
    16  )
    17  
    18  const ID = spdxutil.JSONFormatID
    19  
    20  func SupportedVersions() []string {
    21  	return spdxutil.SupportedVersions(ID)
    22  }
    23  
    24  type EncoderConfig struct {
    25  	Version string
    26  	Pretty  bool // don't include spaces and newlines; same as jq -c
    27  }
    28  
    29  type encoder struct {
    30  	cfg EncoderConfig
    31  }
    32  
    33  func NewFormatEncoderWithConfig(cfg EncoderConfig) (sbom.FormatEncoder, error) {
    34  	return encoder{
    35  		cfg: cfg,
    36  	}, nil
    37  }
    38  
    39  func DefaultEncoderConfig() EncoderConfig {
    40  	return EncoderConfig{
    41  		Version: spdxutil.DefaultVersion,
    42  		Pretty:  false,
    43  	}
    44  }
    45  
    46  func (e encoder) ID() sbom.FormatID {
    47  	return ID
    48  }
    49  
    50  func (e encoder) Aliases() []string {
    51  	return []string{}
    52  }
    53  
    54  func (e encoder) Version() string {
    55  	return e.cfg.Version
    56  }
    57  
    58  func (e encoder) Encode(writer io.Writer, s sbom.SBOM) error {
    59  	latestDoc := spdxhelpers.ToFormatModel(s)
    60  	if latestDoc == nil {
    61  		return fmt.Errorf("unable to convert SBOM to SPDX document")
    62  	}
    63  
    64  	var err error
    65  	var encodeDoc any
    66  	switch e.cfg.Version {
    67  	case "2.1":
    68  		doc := v2_1.Document{}
    69  		err = convert.Document(latestDoc, &doc)
    70  		encodeDoc = doc
    71  	case "2.2":
    72  		doc := v2_2.Document{}
    73  		err = convert.Document(latestDoc, &doc)
    74  		encodeDoc = doc
    75  
    76  	case "2.3":
    77  		doc := v2_3.Document{}
    78  		err = convert.Document(latestDoc, &doc)
    79  		encodeDoc = doc
    80  	default:
    81  		return fmt.Errorf("unsupported SPDX version %q", e.cfg.Version)
    82  	}
    83  
    84  	if err != nil {
    85  		return fmt.Errorf("unable to convert SBOM to SPDX document: %w", err)
    86  	}
    87  
    88  	enc := json.NewEncoder(writer)
    89  
    90  	enc.SetEscapeHTML(false)
    91  
    92  	if e.cfg.Pretty {
    93  		enc.SetIndent("", " ")
    94  	}
    95  
    96  	return enc.Encode(encodeDoc)
    97  }