github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/cmd/syft/internal/options/format.go (about)

     1  package options
     2  
     3  import (
     4  	"github.com/anchore/clio"
     5  	"github.com/anchore/syft/syft/format"
     6  	"github.com/anchore/syft/syft/format/spdxtagvalue"
     7  	"github.com/anchore/syft/syft/sbom"
     8  )
     9  
    10  var _ clio.PostLoader = (*Format)(nil)
    11  
    12  // Format contains all user configuration for output formatting.
    13  type Format struct {
    14  	Pretty        *bool               `yaml:"pretty" json:"pretty" mapstructure:"pretty"`
    15  	Template      FormatTemplate      `yaml:"template" json:"template" mapstructure:"template"`
    16  	SyftJSON      FormatSyftJSON      `yaml:"json" json:"json" mapstructure:"json"`
    17  	SPDXJSON      FormatSPDXJSON      `yaml:"spdx-json" json:"spdx-json" mapstructure:"spdx-json"`
    18  	CyclonedxJSON FormatCyclonedxJSON `yaml:"cyclonedx-json" json:"cyclonedx-json" mapstructure:"cyclonedx-json"`
    19  	CyclonedxXML  FormatCyclonedxXML  `yaml:"cyclonedx-xml" json:"cyclonedx-xml" mapstructure:"cyclonedx-xml"`
    20  }
    21  
    22  func (o *Format) PostLoad() error {
    23  	o.SyftJSON.Pretty = multiLevelOption[bool](false, o.Pretty, o.SyftJSON.Pretty)
    24  	o.SPDXJSON.Pretty = multiLevelOption[bool](false, o.Pretty, o.SPDXJSON.Pretty)
    25  	o.CyclonedxJSON.Pretty = multiLevelOption[bool](false, o.Pretty, o.CyclonedxJSON.Pretty)
    26  	o.CyclonedxXML.Pretty = multiLevelOption[bool](false, o.Pretty, o.CyclonedxXML.Pretty)
    27  
    28  	return nil
    29  }
    30  
    31  func DefaultFormat() Format {
    32  	return Format{
    33  		Template:      DefaultFormatTemplate(),
    34  		SyftJSON:      DefaultFormatJSON(),
    35  		SPDXJSON:      DefaultFormatSPDXJSON(),
    36  		CyclonedxJSON: DefaultFormatCyclonedxJSON(),
    37  		CyclonedxXML:  DefaultFormatCyclonedxXML(),
    38  	}
    39  }
    40  
    41  func (o Format) Encoders() ([]sbom.FormatEncoder, error) {
    42  	return format.EncodersConfig{
    43  		Template:      o.Template.config(),
    44  		SyftJSON:      o.SyftJSON.config(),
    45  		SPDXJSON:      o.SPDXJSON.config(format.AllVersions),                   // we support multiple versions, not just a single version
    46  		SPDXTagValue:  spdxtagvalue.EncoderConfig{Version: format.AllVersions}, // we support multiple versions, not just a single version
    47  		CyclonedxJSON: o.CyclonedxJSON.config(format.AllVersions),              // we support multiple versions, not just a single version
    48  		CyclonedxXML:  o.CyclonedxXML.config(format.AllVersions),               // we support multiple versions, not just a single version
    49  	}.Encoders()
    50  }
    51  
    52  func multiLevelOption[T any](defaultValue T, option ...*T) *T {
    53  	result := defaultValue
    54  	for _, opt := range option {
    55  		if opt != nil {
    56  			result = *opt
    57  		}
    58  	}
    59  	return &result
    60  }