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