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

     1  package golang
     2  
     3  import (
     4  	"regexp"
     5  	"runtime/debug"
     6  	"strings"
     7  
     8  	"github.com/anchore/packageurl-go"
     9  	"github.com/anchore/syft/internal/log"
    10  	"github.com/anchore/syft/syft/file"
    11  	"github.com/anchore/syft/syft/pkg"
    12  )
    13  
    14  func (c *goBinaryCataloger) newGoBinaryPackage(resolver file.Resolver, dep *debug.Module, mainModule, goVersion, architecture string, buildSettings map[string]string, cryptoSettings []string, locations ...file.Location) pkg.Package {
    15  	if dep.Replace != nil {
    16  		dep = dep.Replace
    17  	}
    18  
    19  	licenses, err := c.licenses.getLicenses(resolver, dep.Path, dep.Version)
    20  	if err != nil {
    21  		log.Tracef("error getting licenses for golang package: %s %v", dep.Path, err)
    22  	}
    23  
    24  	p := pkg.Package{
    25  		Name:         dep.Path,
    26  		Version:      dep.Version,
    27  		Licenses:     pkg.NewLicenseSet(licenses...),
    28  		PURL:         packageURL(dep.Path, dep.Version),
    29  		Language:     pkg.Go,
    30  		Type:         pkg.GoModulePkg,
    31  		Locations:    file.NewLocationSet(locations...),
    32  		MetadataType: pkg.GolangBinMetadataType,
    33  		Metadata: pkg.GolangBinMetadata{
    34  			GoCompiledVersion: goVersion,
    35  			H1Digest:          dep.Sum,
    36  			Architecture:      architecture,
    37  			BuildSettings:     buildSettings,
    38  			MainModule:        mainModule,
    39  			GoCryptoSettings:  cryptoSettings,
    40  		},
    41  	}
    42  
    43  	p.SetID()
    44  
    45  	return p
    46  }
    47  
    48  func packageURL(moduleName, moduleVersion string) string {
    49  	// source: https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#golang
    50  	// note: "The version is often empty when a commit is not specified and should be the commit in most cases when available."
    51  
    52  	re := regexp.MustCompile(`(/)[^/]*$`)
    53  	fields := re.Split(moduleName, -1)
    54  	if len(fields) == 0 {
    55  		return ""
    56  	}
    57  	namespace := fields[0]
    58  	name := strings.TrimPrefix(strings.TrimPrefix(moduleName, namespace), "/")
    59  
    60  	if name == "" {
    61  		// this is a "short" url (with no namespace)
    62  		name = namespace
    63  		namespace = ""
    64  	}
    65  
    66  	// The subpath is used to point to a subpath inside a package (e.g. pkg:golang/google.golang.org/genproto#googleapis/api/annotations)
    67  	subpath := "" // TODO: not implemented
    68  
    69  	return packageurl.NewPackageURL(
    70  		packageurl.TypeGolang,
    71  		namespace,
    72  		name,
    73  		moduleVersion,
    74  		nil,
    75  		subpath,
    76  	).ToString()
    77  }