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