Skip to content

Commit

Permalink
Merge pull request anchore#1 from aiwantaozi/work
Browse files Browse the repository at this point in the history
feat: support generate maven dependency tree
  • Loading branch information
gitlawr committed Aug 9, 2022
2 parents 150e23f + 5f1021a commit 3c91ff6
Show file tree
Hide file tree
Showing 11 changed files with 733 additions and 266 deletions.
4 changes: 4 additions & 0 deletions internal/formats/common/cyclonedxhelpers/decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ func getPropertyValue(component *cyclonedx.Component, name string) string {
return ""
}

func isRootComponent(component *cyclonedx.Component) bool {
return getPropertyValue(component, "syft:metadata:isRootPackage") == "true"
}

func collectRelationships(bom *cyclonedx.BOM, s *sbom.SBOM, idMap map[string]interface{}) {
if bom.Dependencies == nil {
return
Expand Down
35 changes: 28 additions & 7 deletions internal/formats/common/cyclonedxhelpers/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/CycloneDX/cyclonedx-go"
"github.com/google/uuid"
"github.com/scylladb/go-set/strset"

"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/artifact"
Expand All @@ -23,9 +24,14 @@ func ToFormatModel(s sbom.SBOM) *cyclonedx.BOM {
cdxBOM.Metadata = toBomDescriptor(s.Descriptor, s.Source)

packages := s.Artifacts.PackageCatalog.Sorted()
components := make([]cyclonedx.Component, len(packages))
for i, p := range packages {
components[i] = encodeComponent(p)
var components []cyclonedx.Component
for _, p := range packages {
comp := encodeComponent(p)
if isRootComponent(&comp) {
cdxBOM.Metadata.Component = &comp
continue
}
components = append(components, comp)
}
components = append(components, toOSComponent(s.Artifacts.LinuxDistribution)...)
cdxBOM.Components = &components
Expand Down Expand Up @@ -133,18 +139,33 @@ func isExpressiblePackageRelationship(ty artifact.RelationshipType) bool {

func toDependencies(relationships []artifact.Relationship) []cyclonedx.Dependency {
result := make([]cyclonedx.Dependency, 0)
resultMap := make(map[string]*strset.Set)
for _, r := range relationships {
exists := isExpressiblePackageRelationship(r.Type)
if !exists {
log.Debugf("unable to convert relationship from CycloneDX 1.4 JSON, dropping: %+v", r)
continue
}

innerDeps := []cyclonedx.Dependency{}
innerDeps = append(innerDeps, cyclonedx.Dependency{Ref: string(r.From.ID())})
ref := string(r.From.ID())
if _, ok := resultMap[ref]; !ok {
resultMap[ref] = strset.New(string(r.To.ID()))
} else {
resultMap[ref].Add(string(r.To.ID()))
}
}

for ref, r := range resultMap {
var deps []cyclonedx.Dependency
for _, v := range r.List() {
deps = append(deps, cyclonedx.Dependency{
Ref: v,
})
}

result = append(result, cyclonedx.Dependency{
Ref: string(r.To.ID()),
Dependencies: &innerDeps,
Ref: ref,
Dependencies: &deps,
})
}
return result
Expand Down
3 changes: 3 additions & 0 deletions syft/pkg/cataloger/common/cpe/java.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ func groupIDsFromPomProperties(properties *pkg.PomProperties) (groupIDs []string
groupIDs = append(groupIDs, cleanGroupID(properties.ArtifactID))
}

if properties.GroupID != "" {
groupIDs = append(groupIDs, cleanGroupID(properties.GroupID))
}
return groupIDs
}

Expand Down
4 changes: 2 additions & 2 deletions syft/pkg/cataloger/java/cataloger.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ func NewJavaCataloger(cfg Config) *common.GenericCataloger {
mode: cfg.SearchByBuildToolsWithMode,
}
rawGlobParsers := map[string]common.RawParserFn{
"**/pom.xml": parseJavaScaffolding(mavenScaffolding, opts),
"**/build.gradle": parseJavaScaffolding(gradleScaffolding, opts),
"**/pom.xml": javaScaffoldingParserFn(mavenScaffolding, opts),
"**/build.gradle": javaScaffoldingParserFn(gradleScaffolding, opts),
}

return common.NewGenericCatalogerWithPreciseLocation(nil, rawGlobParsers, "java-scaffolding-cataloger")
Expand Down
61 changes: 61 additions & 0 deletions syft/pkg/cataloger/java/graph_parser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package java

import (
"bufio"

"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/pkg"
)

type parseLine func(line string) (level int, pkg *pkg.Package, err error)

type isLineValid func(line string) (valid bool)

// parseGraph is a common framework to get packages and relationships from dependency tree
// example:
// +--- org.apache.commons:commons-math3:3.6.1
// +--- com.google.guava:guava:30.1.1-jre
// | +--- com.google.guava:failureaccess:1.0.1
// | \--- com.google.j2objc:j2objc-annotations:1.3
// +--- org.apache.logging.log4j:log4j-core:2.12.0
// | \--- org.apache.logging.log4j:log4j-api:2.12.0
// \--- junit:junit:4.13.2
// \--- org.hamcrest:hamcrest-core:1.3
func parseGraph(scanner *bufio.Scanner, isLineValid isLineValid, parser parseLine) (directlyDependencies, pkgs []*pkg.Package, relationships []artifact.Relationship, err error) {
var parents []*pkg.Package
for scanner.Scan() {
var line = scanner.Text()

if ok := isLineValid(line); !ok {
continue
}

level, child, err := parser(line)
if err != nil {
return nil, nil, nil, err
}

if len(parents) >= level {
parents = parents[:level-1]
}

if level == 1 {
directlyDependencies = append(directlyDependencies, child)
} else {
parent := parents[len(parents)-1]
var fromID = &PackageURL{Package: *parent}
var toID = &PackageURL{Package: *child}
relation := artifact.Relationship{
From: fromID,
To: toID,
Type: artifact.DependencyOfRelationship,
}

relationships = append(relationships, relation)
}
parents = append(parents, child)
pkgs = append(pkgs, child)
}

return directlyDependencies, pkgs, relationships, nil
}
14 changes: 14 additions & 0 deletions syft/pkg/cataloger/java/package_id.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package java

import (
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/pkg"
)

type PackageURL struct {
pkg.Package
}

func (p *PackageURL) ID() artifact.ID {
return artifact.ID(packageURL(p.Package))
}
13 changes: 11 additions & 2 deletions syft/pkg/cataloger/java/parse_pom_xml.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func parsePomXML(path string, reader io.Reader) (*pkg.PomProject, error) {
return nil, fmt.Errorf("unable to unmarshal pom.xml: %w", err)
}

return &pkg.PomProject{
pkg := &pkg.PomProject{
Path: path,
Parent: pomParent(project.Parent),
GroupID: project.GroupID,
Expand All @@ -33,7 +33,16 @@ func parsePomXML(path string, reader io.Reader) (*pkg.PomProject, error) {
Name: project.Name,
Description: cleanDescription(project.Description),
URL: project.URL,
}, nil
}

if pkg.GroupID == "" {
pkg.GroupID = pkg.Parent.GroupID
}

if pkg.Version == "" {
pkg.Version = pkg.Parent.Version
}
return pkg, nil
}

func pomParent(parent gopom.Parent) (result *pkg.PomParent) {
Expand Down
Loading

0 comments on commit 3c91ff6

Please sign in to comment.