github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/syft/pkg/cataloger/dart/parse_pubspec_lock.go (about) 1 package dart 2 3 import ( 4 "fmt" 5 "net/url" 6 "sort" 7 8 "gopkg.in/yaml.v3" 9 10 "github.com/anchore/syft/syft/artifact" 11 "github.com/anchore/syft/syft/file" 12 "github.com/anchore/syft/syft/pkg" 13 "github.com/anchore/syft/syft/pkg/cataloger/generic" 14 "github.com/lineaje-labs/syft/internal/log" 15 ) 16 17 var _ generic.Parser = parsePubspecLock 18 19 const defaultPubRegistry string = "https://pub.dartlang.org" 20 21 type pubspecLock struct { 22 Packages map[string]pubspecLockPackage `yaml:"packages"` 23 Sdks map[string]string `yaml:"sdks"` 24 } 25 26 type pubspecLockPackage struct { 27 Dependency string `yaml:"dependency" mapstructure:"dependency"` 28 Description pubspecLockDescription `yaml:"description" mapstructure:"description"` 29 Source string `yaml:"source" mapstructure:"source"` 30 Version string `yaml:"version" mapstructure:"version"` 31 } 32 33 type pubspecLockDescription struct { 34 Name string `yaml:"name" mapstructure:"name"` 35 URL string `yaml:"url" mapstructure:"url"` 36 Path string `yaml:"path" mapstructure:"path"` 37 Ref string `yaml:"ref" mapstructure:"ref"` 38 ResolvedRef string `yaml:"resolved-ref" mapstructure:"resolved-ref"` 39 } 40 41 func (p *pubspecLockDescription) UnmarshalYAML(value *yaml.Node) error { 42 type pld pubspecLockDescription 43 var p2 pld 44 45 if value.Decode(&p.Name) == nil { 46 return nil 47 } 48 49 if err := value.Decode(&p2); err != nil { 50 return err 51 } 52 53 *p = pubspecLockDescription(p2) 54 55 return nil 56 } 57 58 func parsePubspecLock( 59 _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser, 60 ) ([]pkg.Package, []artifact.Relationship, error) { 61 var pkgs []pkg.Package 62 63 dec := yaml.NewDecoder(reader) 64 65 var p pubspecLock 66 if err := dec.Decode(&p); err != nil { 67 return nil, nil, fmt.Errorf("failed to parse pubspec.lock file: %w", err) 68 } 69 70 var names []string 71 for name := range p.Packages { 72 names = append(names, name) 73 } 74 75 // always ensure there is a stable ordering of packages 76 sort.Strings(names) 77 78 for _, name := range names { 79 pubPkg := p.Packages[name] 80 pkgs = append(pkgs, 81 newPubspecLockPackage( 82 name, 83 pubPkg, 84 reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), 85 ), 86 ) 87 } 88 89 return pkgs, nil, nil 90 } 91 92 func (p *pubspecLockPackage) getVcsURL() string { 93 if p.Source == "git" { 94 if p.Description.Path == "." { 95 return fmt.Sprintf("%s@%s", p.Description.URL, p.Description.ResolvedRef) 96 } 97 98 return fmt.Sprintf("%s@%s#%s", p.Description.URL, p.Description.ResolvedRef, p.Description.Path) 99 } 100 101 return "" 102 } 103 104 func (p *pubspecLockPackage) getHostedURL() string { 105 if p.Source == "hosted" && p.Description.URL != defaultPubRegistry { 106 u, err := url.Parse(p.Description.URL) 107 if err != nil { 108 log.Debugf("Unable to parse registry url %w", err) 109 return p.Description.URL 110 } 111 return u.Host 112 } 113 114 return "" 115 }