github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/erlang/parse_rebar_lock.go (about)

     1  package erlang
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/anchore/syft/internal/log"
     7  	"github.com/anchore/syft/internal/unknown"
     8  	"github.com/anchore/syft/syft/artifact"
     9  	"github.com/anchore/syft/syft/file"
    10  	"github.com/anchore/syft/syft/pkg"
    11  	"github.com/anchore/syft/syft/pkg/cataloger/generic"
    12  )
    13  
    14  // parseRebarLock parses a rebar.lock and returns the discovered Elixir packages.
    15  //
    16  
    17  func parseRebarLock(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
    18  	doc, err := parseErlang(reader)
    19  	if err != nil {
    20  		return nil, nil, err
    21  	}
    22  
    23  	pkgMap := make(map[string]*pkg.Package)
    24  
    25  	// rebar.lock structure is:
    26  	// [
    27  	//   ["version", [
    28  	//     [<<"package-name">>, ["version-type", "version"]...
    29  	//   ],
    30  	//   [
    31  	//     [pkg_hash, [
    32  	//       [<<"package-name">>, <<"package-hash">>]
    33  	//     ],
    34  	//     [pkg_hash_ext, [
    35  	//       [<<"package-name">>, <<"package-hash">>]
    36  	//     ]
    37  	//   ]
    38  	// ]
    39  
    40  	versions := doc.Get(0)
    41  	deps := versions.Get(1)
    42  
    43  	for _, dep := range deps.Slice() {
    44  		name := dep.Get(0).String()
    45  		versionNode := dep.Get(1)
    46  		versionType := versionNode.Get(0).String()
    47  		version := versionNode.Get(2).String()
    48  
    49  		// capture git hashes if no version specified
    50  		if versionType == "git" {
    51  			version = versionNode.Get(2).Get(1).String()
    52  		}
    53  
    54  		p := newPackageFromRebar(
    55  			pkg.ErlangRebarLockEntry{
    56  				Name:    name,
    57  				Version: version,
    58  			},
    59  			reader.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
    60  		)
    61  
    62  		pkgMap[name] = &p
    63  	}
    64  
    65  	hashes := doc.Get(1)
    66  	for _, hashStruct := range hashes.Slice() {
    67  		hashType := hashStruct.Get(0).String()
    68  
    69  		for _, hashValue := range hashStruct.Get(1).Slice() {
    70  			name := hashValue.Get(0).String()
    71  			hash := hashValue.Get(1).String()
    72  
    73  			sourcePkg := pkgMap[name]
    74  			if sourcePkg == nil {
    75  				log.WithFields("package", name).Debug("unable find source package")
    76  				continue
    77  			}
    78  			metadata, ok := sourcePkg.Metadata.(pkg.ErlangRebarLockEntry)
    79  			if !ok {
    80  				log.WithFields("package", name).Debug("unable to extract rebar.lock metadata to add hash metadata")
    81  				continue
    82  			}
    83  
    84  			switch hashType {
    85  			case "pkg_hash":
    86  				metadata.PkgHash = hash
    87  			case "pkg_hash_ext":
    88  				metadata.PkgHashExt = hash
    89  			}
    90  			sourcePkg.Metadata = metadata
    91  		}
    92  	}
    93  
    94  	var packages []pkg.Package
    95  	for _, p := range pkgMap {
    96  		p.SetID()
    97  		packages = append(packages, *p)
    98  	}
    99  	return packages, nil, unknown.IfEmptyf(packages, "unable to determine packages")
   100  }
   101  
   102  // integrity check
   103  var _ generic.Parser = parseRebarLock