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