github.com/anchore/syft@v1.38.2/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 _ interface {
    11  	clio.PostLoader
    12  	clio.FieldDescriber
    13  } = (*Format)(nil)
    14  
    15  // Format contains all user configuration for output formatting.
    16  type Format struct {
    17  	Pretty        *bool               `yaml:"pretty" json:"pretty" mapstructure:"pretty"`
    18  	Template      FormatTemplate      `yaml:"template" json:"template" mapstructure:"template" description:"all template format options"`
    19  	SyftJSON      FormatSyftJSON      `yaml:"json" json:"json" mapstructure:"json" description:"all syft-json format options"`
    20  	SPDXJSON      FormatSPDXJSON      `yaml:"spdx-json" json:"spdx-json" mapstructure:"spdx-json" description:"all spdx-json format options"`
    21  	CyclonedxJSON FormatCyclonedxJSON `yaml:"cyclonedx-json" json:"cyclonedx-json" mapstructure:"cyclonedx-json" description:"all cyclonedx-json format options"`
    22  	CyclonedxXML  FormatCyclonedxXML  `yaml:"cyclonedx-xml" json:"cyclonedx-xml" mapstructure:"cyclonedx-xml" description:"all cyclonedx-xml format options"`
    23  }
    24  
    25  func (o *Format) PostLoad() error {
    26  	o.SyftJSON.Pretty = multiLevelOption[bool](false, o.Pretty, o.SyftJSON.Pretty)
    27  	o.SPDXJSON.Pretty = multiLevelOption[bool](false, o.Pretty, o.SPDXJSON.Pretty)
    28  	o.CyclonedxJSON.Pretty = multiLevelOption[bool](false, o.Pretty, o.CyclonedxJSON.Pretty)
    29  	o.CyclonedxXML.Pretty = multiLevelOption[bool](false, o.Pretty, o.CyclonedxXML.Pretty)
    30  
    31  	return nil
    32  }
    33  
    34  func (o *Format) DescribeFields(descriptions clio.FieldDescriptionSet) {
    35  	descriptions.Add(&o.Pretty, `default value for all formats that support the "pretty" option (default is unset)`)
    36  	descriptions.Add(&o.SyftJSON, `all syft-json format options`)
    37  	descriptions.Add(&o.SyftJSON.Legacy, `transform any syft-json output to conform to an approximation of the v11.0.1 schema. This includes:
    38  - using the package metadata type names from before v12 of the JSON schema (changed in https://github.com/anchore/syft/pull/1983)
    39  
    40  Note: this will still include package types and fields that were added at or after json schema v12. This means
    41  that output might not strictly be json schema v11 compliant, however, for consumers that require time to port
    42  over to the final syft 1.0 json output this option can be used to ease the transition.
    43  
    44  Note: long term support for this option is not guaranteed (it may change or break at any time)`)
    45  
    46  	descriptions.Add(&o.Template.Path, `path to the template file to use when rendering the output with the template output format.
    47  Note that all template paths are based on the current syft-json schema`)
    48  	descriptions.Add(&o.Template.Legacy, `if true, uses the go structs for the syft-json format for templating.
    49  if false, uses the syft-json output for templating (which follows the syft JSON schema exactly).
    50  
    51  Note: long term support for this option is not guaranteed (it may change or break at any time)`)
    52  
    53  	prettyDescription := `include space indentation and newlines
    54  note: inherits default value from 'format.pretty' or 'false' if parent is unset`
    55  	descriptions.Add(&o.SyftJSON.Pretty, prettyDescription)
    56  	descriptions.Add(&o.SPDXJSON.Pretty, prettyDescription)
    57  	descriptions.Add(&o.CyclonedxJSON.Pretty, prettyDescription)
    58  	descriptions.Add(&o.CyclonedxXML.Pretty, prettyDescription)
    59  }
    60  
    61  func DefaultFormat() Format {
    62  	return Format{
    63  		Template:      DefaultFormatTemplate(),
    64  		SyftJSON:      DefaultFormatJSON(),
    65  		SPDXJSON:      DefaultFormatSPDXJSON(),
    66  		CyclonedxJSON: DefaultFormatCyclonedxJSON(),
    67  		CyclonedxXML:  DefaultFormatCyclonedxXML(),
    68  	}
    69  }
    70  
    71  func (o Format) Encoders() ([]sbom.FormatEncoder, error) {
    72  	return format.EncodersConfig{
    73  		Template:      o.Template.config(),
    74  		SyftJSON:      o.SyftJSON.config(),
    75  		SPDXJSON:      o.SPDXJSON.config(format.AllVersions),                   // we support multiple versions, not just a single version
    76  		SPDXTagValue:  spdxtagvalue.EncoderConfig{Version: format.AllVersions}, // we support multiple versions, not just a single version
    77  		CyclonedxJSON: o.CyclonedxJSON.config(format.AllVersions),              // we support multiple versions, not just a single version
    78  		CyclonedxXML:  o.CyclonedxXML.config(format.AllVersions),               // we support multiple versions, not just a single version
    79  	}.Encoders()
    80  }
    81  
    82  func multiLevelOption[T any](defaultValue T, option ...*T) *T {
    83  	result := defaultValue
    84  	for _, opt := range option {
    85  		if opt != nil {
    86  			result = *opt
    87  		}
    88  	}
    89  	return &result
    90  }