github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/gosbom/pkg/cataloger/golang/package.go (about)

     1  package golang
     2  
     3  import (
     4  	"regexp"
     5  	"runtime/debug"
     6  	"strings"
     7  
     8  	"github.com/nextlinux/gosbom/gosbom/file"
     9  	"github.com/nextlinux/gosbom/gosbom/pkg"
    10  	"github.com/nextlinux/gosbom/internal/log"
    11  
    12  	"github.com/anchore/packageurl-go"
    13  )
    14  
    15  func (c *goBinaryCataloger) newGoBinaryPackage(resolver file.Resolver, dep *debug.Module, mainModule, goVersion, architecture string, buildSettings map[string]string, locations ...file.Location) pkg.Package {
    16  	if dep.Replace != nil {
    17  		dep = dep.Replace
    18  	}
    19  
    20  	licenses, err := c.licenses.getLicenses(resolver, dep.Path, dep.Version)
    21  	if err != nil {
    22  		log.Tracef("error getting licenses for golang package: %s %v", dep.Path, err)
    23  	}
    24  
    25  	p := pkg.Package{
    26  		Name:         dep.Path,
    27  		Version:      dep.Version,
    28  		Licenses:     pkg.NewLicenseSet(licenses...),
    29  		PURL:         packageURL(dep.Path, dep.Version),
    30  		Language:     pkg.Go,
    31  		Type:         pkg.GoModulePkg,
    32  		Locations:    file.NewLocationSet(locations...),
    33  		MetadataType: pkg.GolangBinMetadataType,
    34  		Metadata: pkg.GolangBinMetadata{
    35  			GoCompiledVersion: goVersion,
    36  			H1Digest:          dep.Sum,
    37  			Architecture:      architecture,
    38  			BuildSettings:     buildSettings,
    39  			MainModule:        mainModule,
    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  }