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

     1  package cpp
     2  
     3  import (
     4  	"bufio"
     5  	"context"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  	"strings"
    10  
    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  var _ generic.Parser = parseConanfile
    18  
    19  // parseConanfile is a parser function for conanfile.txt contents, returning all packages discovered.
    20  func parseConanfile(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
    21  	r := bufio.NewReader(reader)
    22  	inRequirements := false
    23  	var pkgs []pkg.Package
    24  	for {
    25  		line, err := r.ReadString('\n')
    26  		switch {
    27  		case errors.Is(io.EOF, err):
    28  			return pkgs, nil, nil
    29  		case err != nil:
    30  			return nil, nil, fmt.Errorf("failed to parse conanfile.txt file: %w", err)
    31  		}
    32  
    33  		switch {
    34  		case strings.Contains(line, "[requires]"):
    35  			inRequirements = true
    36  		case strings.ContainsAny(line, "[]") || strings.HasPrefix(strings.TrimSpace(line), "#"):
    37  			inRequirements = false
    38  		}
    39  
    40  		m := pkg.ConanfileEntry{
    41  			Ref: strings.Trim(line, "\n"),
    42  		}
    43  
    44  		if !inRequirements {
    45  			continue
    46  		}
    47  
    48  		p := newConanfilePackage(
    49  			m,
    50  			reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
    51  		)
    52  		if p == nil {
    53  			continue
    54  		}
    55  
    56  		pkgs = append(pkgs, *p)
    57  	}
    58  }