Skip to content

Commit

Permalink
Merge pull request #2 from noqcks/benji/dotnet-deps
Browse files Browse the repository at this point in the history
Benji/dotnet deps
  • Loading branch information
noqcks authored Sep 17, 2023
2 parents 7d2ddc2 + 810b473 commit 3f58258
Show file tree
Hide file tree
Showing 6 changed files with 453 additions and 205 deletions.
31 changes: 24 additions & 7 deletions syft/pkg/cataloger/dotnet/package.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package dotnet

import (
"fmt"
"regexp"
"strings"

"github.com/anchore/packageurl-go"
Expand All @@ -9,13 +11,7 @@ import (
)

func newDotnetDepsPackage(nameVersion string, lib dotnetDepsLibrary, locations ...file.Location) *pkg.Package {
if lib.Type != "package" {
return nil
}

fields := strings.Split(nameVersion, "/")
name := fields[0]
version := fields[1]
name, version := extractNameAndVersion(nameVersion)

m := pkg.DotnetDepsMetadata{
Name: name,
Expand All @@ -41,6 +37,27 @@ func newDotnetDepsPackage(nameVersion string, lib dotnetDepsLibrary, locations .
return p
}

func getDepsJSONFilePrefix(p string) string {
r := regexp.MustCompile(`([^\/]+)\.deps\.json$`)
match := r.FindStringSubmatch(p)
if len(match) > 1 {
return match[1]
}
return ""
}

func extractNameAndVersion(nameVersion string) (name, version string) {
fields := strings.Split(nameVersion, "/")
name = fields[0]
version = fields[1]
return
}

func createNameAndVersion(name, version string) (nameVersion string) {
nameVersion = fmt.Sprintf("%s/%s", name, version)
return
}

func packageURL(m pkg.DotnetDepsMetadata) string {
var qualifiers packageurl.Qualifiers

Expand Down
65 changes: 61 additions & 4 deletions syft/pkg/cataloger/dotnet/parse_dotnet_deps.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"sort"

"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
Expand All @@ -13,8 +14,18 @@ import (

var _ generic.Parser = parseDotnetDeps

type dotnetRuntimeTarget struct {
Name string `json:"name"`
}

type dotnetDepsTarget struct {
Dependencies map[string]string `json:"dependencies"`
Runtime map[string]struct{} `json:"runtime"`
}
type dotnetDeps struct {
Libraries map[string]dotnetDepsLibrary `json:"libraries"`
RuntimeTarget dotnetRuntimeTarget `json:"runtimeTarget"`
Targets map[string]map[string]dotnetDepsTarget `json:"targets"`
Libraries map[string]dotnetDepsLibrary `json:"libraries"`
}

type dotnetDepsLibrary struct {
Expand All @@ -24,8 +35,11 @@ type dotnetDepsLibrary struct {
HashPath string `json:"hashPath"`
}

//nolint:funlen
func parseDotnetDeps(_ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
var pkgs []pkg.Package
var pkgMap = make(map[string]pkg.Package)
var relationships []artifact.Relationship

dec := json.NewDecoder(reader)

Expand All @@ -35,11 +49,9 @@ func parseDotnetDeps(_ file.Resolver, _ *generic.Environment, reader file.Locati
}

var names []string

for nameVersion := range p.Libraries {
names = append(names, nameVersion)
}

// sort the names so that the order of the packages is deterministic
sort.Strings(names)

Expand All @@ -53,8 +65,53 @@ func parseDotnetDeps(_ file.Resolver, _ *generic.Environment, reader file.Locati

if dotnetPkg != nil {
pkgs = append(pkgs, *dotnetPkg)
pkgMap[nameVersion] = *dotnetPkg
}
}

rootName := getDepsJSONFilePrefix(reader.AccessPath())
if rootName == "" {
return nil, nil, fmt.Errorf("unable to determine root package name from deps.json file: %s", reader.AccessPath())
}
var rootpkg *pkg.Package
for nameVersion, lib := range p.Libraries {
name, _ := extractNameAndVersion(nameVersion)
if lib.Type == "project" && name == rootName {
rootpkg = newDotnetDepsPackage(
nameVersion,
lib,
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
)
}
}

if rootpkg == nil {
return nil, nil, fmt.Errorf("unable to determine root package from deps.json file: %s", reader.AccessPath())
}

for pkgNameVersion, target := range p.Targets[p.RuntimeTarget.Name] {
for depName, depVersion := range target.Dependencies {
depNameVersion := createNameAndVersion(depName, depVersion)
depPkg, ok := pkgMap[depNameVersion]
if !ok {
log.Debug("unable to find package in map", depNameVersion)
continue
}
pkg, ok := pkgMap[pkgNameVersion]
if !ok {
log.Debug("unable to find package in map", pkgNameVersion)
continue
}
rel := artifact.Relationship{
From: depPkg,
To: pkg,
Type: artifact.DependencyOfRelationship,
}
relationships = append(relationships, rel)
}
}

return pkgs, nil, nil
pkg.Sort(pkgs)
pkg.SortRelationships(relationships)
return pkgs, relationships, nil
}
Loading

0 comments on commit 3f58258

Please sign in to comment.