github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/syft/file/cataloger/filecontent/cataloger.go (about)

     1  package filecontent
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/base64"
     6  	"fmt"
     7  	"io"
     8  
     9  	"github.com/anchore/syft/internal"
    10  	"github.com/anchore/syft/internal/log"
    11  	"github.com/anchore/syft/syft/file"
    12  )
    13  
    14  // Deprecated: will be removed in syft v1.0.0
    15  type Cataloger struct {
    16  	globs                     []string
    17  	skipFilesAboveSizeInBytes int64
    18  }
    19  
    20  // Deprecated: will be removed in syft v1.0.0
    21  func NewCataloger(globs []string, skipFilesAboveSize int64) (*Cataloger, error) {
    22  	return &Cataloger{
    23  		globs:                     globs,
    24  		skipFilesAboveSizeInBytes: skipFilesAboveSize,
    25  	}, nil
    26  }
    27  
    28  func (i *Cataloger) Catalog(resolver file.Resolver) (map[file.Coordinates]string, error) {
    29  	results := make(map[file.Coordinates]string)
    30  	var locations []file.Location
    31  
    32  	locations, err := resolver.FilesByGlob(i.globs...)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  	for _, location := range locations {
    37  		metadata, err := resolver.FileMetadataByLocation(location)
    38  		if err != nil {
    39  			return nil, err
    40  		}
    41  
    42  		if i.skipFilesAboveSizeInBytes > 0 && metadata.Size() > i.skipFilesAboveSizeInBytes {
    43  			continue
    44  		}
    45  
    46  		result, err := i.catalogLocation(resolver, location)
    47  		if internal.IsErrPathPermission(err) {
    48  			log.Debugf("file contents cataloger skipping - %+v", err)
    49  			continue
    50  		}
    51  		if err != nil {
    52  			return nil, err
    53  		}
    54  		results[location.Coordinates] = result
    55  	}
    56  	log.Debugf("file contents cataloger processed %d files", len(results))
    57  
    58  	return results, nil
    59  }
    60  
    61  func (i *Cataloger) catalogLocation(resolver file.Resolver, location file.Location) (string, error) {
    62  	contentReader, err := resolver.FileContentsByLocation(location)
    63  	if err != nil {
    64  		return "", err
    65  	}
    66  	defer internal.CloseAndLogError(contentReader, location.VirtualPath)
    67  
    68  	buf := &bytes.Buffer{}
    69  	encoder := base64.NewEncoder(base64.StdEncoding, buf)
    70  	if _, err = io.Copy(encoder, contentReader); err != nil {
    71  		return "", internal.ErrPath{Context: "contents-cataloger", Path: location.RealPath, Err: err}
    72  	}
    73  	// note: it's important to close the reader before reading from the buffer since closing will flush the remaining bytes
    74  	if err := encoder.Close(); err != nil {
    75  		return "", fmt.Errorf("unable to close base64 encoder: %w", err)
    76  	}
    77  
    78  	return buf.String(), nil
    79  }