github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/gosbom/pkg/cataloger/cpp/parse_conanlock.go (about)

     1  package cpp
     2  
     3  import (
     4  	"encoding/json"
     5  	"strings"
     6  
     7  	"github.com/nextlinux/gosbom/gosbom/artifact"
     8  	"github.com/nextlinux/gosbom/gosbom/file"
     9  	"github.com/nextlinux/gosbom/gosbom/pkg"
    10  	"github.com/nextlinux/gosbom/gosbom/pkg/cataloger/generic"
    11  )
    12  
    13  var _ generic.Parser = parseConanlock
    14  
    15  type conanLock struct {
    16  	GraphLock struct {
    17  		Nodes map[string]struct {
    18  			Ref            string   `json:"ref"`
    19  			PackageID      string   `json:"package_id"`
    20  			Context        string   `json:"context"`
    21  			Prev           string   `json:"prev"`
    22  			Requires       []string `json:"requires"`
    23  			PythonRequires string   `json:"py_requires"`
    24  			Options        string   `json:"options"`
    25  			Path           string   `json:"path"`
    26  		} `json:"nodes"`
    27  	} `json:"graph_lock"`
    28  	Version     string `json:"version"`
    29  	ProfileHost string `json:"profile_host"`
    30  }
    31  
    32  // parseConanlock is a parser function for conan.lock contents, returning all packages discovered.
    33  func parseConanlock(_ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
    34  	var pkgs []pkg.Package
    35  	var cl conanLock
    36  	if err := json.NewDecoder(reader).Decode(&cl); err != nil {
    37  		return nil, nil, err
    38  	}
    39  	for _, node := range cl.GraphLock.Nodes {
    40  		metadata := pkg.ConanLockMetadata{
    41  			Ref:     node.Ref,
    42  			Options: parseOptions(node.Options),
    43  			Path:    node.Path,
    44  			Context: node.Context,
    45  		}
    46  
    47  		p := newConanlockPackage(
    48  			metadata,
    49  			reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
    50  		)
    51  
    52  		if p != nil {
    53  			pkgs = append(pkgs, *p)
    54  		}
    55  	}
    56  
    57  	return pkgs, nil, nil
    58  }
    59  
    60  func parseOptions(options string) map[string]string {
    61  	o := make(map[string]string)
    62  	if len(options) == 0 {
    63  		return nil
    64  	}
    65  
    66  	kvps := strings.Split(options, "\n")
    67  	for _, kvp := range kvps {
    68  		kv := strings.Split(kvp, "=")
    69  		if len(kv) == 2 {
    70  			o[kv[0]] = kv[1]
    71  		}
    72  	}
    73  
    74  	return o
    75  }