github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/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/internal/log" 11 "github.com/anchore/syft/syft/artifact" 12 "github.com/anchore/syft/syft/file" 13 "github.com/anchore/syft/syft/pkg" 14 "github.com/anchore/syft/syft/pkg/cataloger/generic" 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(_ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { 59 var pkgs []pkg.Package 60 61 dec := yaml.NewDecoder(reader) 62 63 var p pubspecLock 64 if err := dec.Decode(&p); err != nil { 65 return nil, nil, fmt.Errorf("failed to parse pubspec.lock file: %w", err) 66 } 67 68 var names []string 69 for name := range p.Packages { 70 names = append(names, name) 71 } 72 73 // always ensure there is a stable ordering of packages 74 sort.Strings(names) 75 76 for _, name := range names { 77 pubPkg := p.Packages[name] 78 pkgs = append(pkgs, 79 newPubspecLockPackage( 80 name, 81 pubPkg, 82 reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), 83 ), 84 ) 85 } 86 87 return pkgs, nil, nil 88 } 89 90 func (p *pubspecLockPackage) getVcsURL() string { 91 if p.Source == "git" { 92 if p.Description.Path == "." { 93 return fmt.Sprintf("%s@%s", p.Description.URL, p.Description.ResolvedRef) 94 } 95 96 return fmt.Sprintf("%s@%s#%s", p.Description.URL, p.Description.ResolvedRef, p.Description.Path) 97 } 98 99 return "" 100 } 101 102 func (p *pubspecLockPackage) getHostedURL() string { 103 if p.Source == "hosted" && p.Description.URL != defaultPubRegistry { 104 u, err := url.Parse(p.Description.URL) 105 if err != nil { 106 log.Debugf("Unable to parse registry url %w", err) 107 return p.Description.URL 108 } 109 return u.Host 110 } 111 112 return "" 113 }