github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/pkg/cataloger/elixir/parse_mix_lock.go (about) 1 package elixir 2 3 import ( 4 "bufio" 5 "context" 6 "errors" 7 "fmt" 8 "io" 9 "regexp" 10 11 "github.com/anchore/syft/internal/log" 12 "github.com/anchore/syft/syft/artifact" 13 "github.com/anchore/syft/syft/file" 14 "github.com/anchore/syft/syft/pkg" 15 "github.com/anchore/syft/syft/pkg/cataloger/generic" 16 ) 17 18 // integrity check 19 var _ generic.Parser = parseMixLock 20 21 var mixLockDelimiter = regexp.MustCompile(`[%{}\n" ,:]+`) 22 23 // parseMixLock parses a mix.lock and returns the discovered Elixir packages. 24 func parseMixLock(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { 25 r := bufio.NewReader(reader) 26 27 var packages []pkg.Package 28 for { 29 line, err := r.ReadString('\n') 30 switch { 31 case errors.Is(io.EOF, err): 32 return packages, nil, nil 33 case err != nil: 34 return nil, nil, fmt.Errorf("failed to parse mix.lock file: %w", err) 35 } 36 tokens := mixLockDelimiter.Split(line, -1) 37 if len(tokens) < 6 { 38 continue 39 } 40 name, version, hash, hashExt := tokens[1], tokens[4], tokens[5], tokens[len(tokens)-2] 41 42 if name == "" { 43 log.WithFields("path", reader.RealPath).Debug("skipping empty package name from mix.lock file") 44 continue 45 } 46 47 packages = append(packages, 48 newPackage( 49 pkg.ElixirMixLockEntry{ 50 Name: name, 51 Version: version, 52 PkgHash: hash, 53 PkgHashExt: hashExt, 54 }, 55 reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), 56 ), 57 ) 58 } 59 }