github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/syft/pkg/cataloger/cpp/package.go (about) 1 package cpp 2 3 import ( 4 "strings" 5 6 "github.com/anchore/packageurl-go" 7 "github.com/anchore/syft/syft/file" 8 "github.com/anchore/syft/syft/pkg" 9 ) 10 11 type conanRef struct { 12 Name string 13 Version string 14 User string 15 Channel string 16 Revision string 17 Timestamp string 18 } 19 20 func splitConanRef(ref string) *conanRef { 21 // Conan ref format is: 22 // pkg/0.1@user/channel#rrev%timestamp 23 // This method is based on conan's ref.loads method: 24 // https://github.com/conan-io/conan/blob/release/2.0/conans/model/recipe_ref.py#L93C21-L93C21 25 26 var cref conanRef 27 28 // timestamp 29 tokens := strings.Split(ref, "%") 30 text := tokens[0] 31 if len(tokens) == 2 { 32 cref.Timestamp = tokens[1] 33 } 34 35 // revision 36 tokens = strings.Split(text, "#") 37 ref = tokens[0] 38 if len(tokens) == 2 { 39 cref.Revision = tokens[1] 40 } 41 42 // name and version are always given 43 tokens = strings.Split(ref, "@") 44 nameAndVersion := strings.Split(tokens[0], "/") 45 if len(nameAndVersion) < 2 || nameAndVersion[0] == "" || nameAndVersion[1] == "" { 46 return nil 47 } 48 cref.Name = nameAndVersion[0] 49 cref.Version = nameAndVersion[1] 50 // user and channel 51 if len(tokens) == 2 && tokens[1] != "" { 52 tokens = strings.Split(tokens[1], "/") 53 if len(tokens) == 2 { 54 cref.User = tokens[0] 55 cref.Channel = tokens[1] 56 } 57 } 58 return &cref 59 } 60 61 func newConanfilePackage(m pkg.ConanMetadata, locations ...file.Location) *pkg.Package { 62 ref := splitConanRef(m.Ref) 63 if ref == nil { 64 return nil 65 } 66 67 p := pkg.Package{ 68 Name: ref.Name, 69 Version: ref.Version, 70 Locations: file.NewLocationSet(locations...), 71 PURL: packageURL(ref), 72 Language: pkg.CPP, 73 Type: pkg.ConanPkg, 74 MetadataType: pkg.ConanMetadataType, 75 Metadata: m, 76 } 77 78 p.SetID() 79 80 return &p 81 } 82 83 func newConanlockPackage(m pkg.ConanLockMetadata, locations ...file.Location) *pkg.Package { 84 ref := splitConanRef(m.Ref) 85 if ref == nil { 86 return nil 87 } 88 89 p := pkg.Package{ 90 Name: ref.Name, 91 Version: ref.Version, 92 Locations: file.NewLocationSet(locations...), 93 PURL: packageURL(ref), 94 Language: pkg.CPP, 95 Type: pkg.ConanPkg, 96 MetadataType: pkg.ConanLockMetadataType, 97 Metadata: m, 98 } 99 100 p.SetID() 101 102 return &p 103 } 104 105 func packageURL(ref *conanRef) string { 106 qualifiers := packageurl.Qualifiers{} 107 if ref.Channel != "" { 108 qualifiers = append(qualifiers, packageurl.Qualifier{ 109 Key: "channel", 110 Value: ref.Channel, 111 }) 112 } 113 return packageurl.NewPackageURL( 114 packageurl.TypeConan, 115 ref.User, 116 ref.Name, 117 ref.Version, 118 qualifiers, 119 "", 120 ).ToString() 121 }