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

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