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 }