github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/pkg/cataloger/php/parse_composer_lock.go (about)

     1  package php
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  
    10  	"github.com/anchore/syft/syft/artifact"
    11  	"github.com/anchore/syft/syft/file"
    12  	"github.com/anchore/syft/syft/pkg"
    13  	"github.com/anchore/syft/syft/pkg/cataloger/generic"
    14  )
    15  
    16  var _ generic.Parser = parseComposerLock
    17  
    18  type parsedLockData struct {
    19  	License []string `json:"license"`
    20  	pkg.PhpComposerLockEntry
    21  }
    22  
    23  type composerLock struct {
    24  	Packages   []parsedLockData `json:"packages"`
    25  	PackageDev []parsedLockData `json:"packages-dev"` // TODO: these are not currently included as packages in the SBOM... should they be?
    26  }
    27  
    28  // parseComposerLock is a parser function for Composer.lock contents, returning "Default" php packages discovered.
    29  func parseComposerLock(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
    30  	pkgs := make([]pkg.Package, 0)
    31  	dec := json.NewDecoder(reader)
    32  
    33  	for {
    34  		var lock composerLock
    35  		if err := dec.Decode(&lock); errors.Is(err, io.EOF) {
    36  			break
    37  		} else if err != nil {
    38  			return nil, nil, fmt.Errorf("failed to parse composer.lock file: %w", err)
    39  		}
    40  		for _, pd := range lock.Packages {
    41  			pkgs = append(
    42  				pkgs,
    43  				newComposerLockPackage(
    44  					pd,
    45  					reader.Location,
    46  				),
    47  			)
    48  		}
    49  	}
    50  
    51  	return pkgs, nil, nil
    52  }