github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/syft/pkg/cataloger/elixir/parse_mix_lock.go (about)

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