Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FlattenGraph for GraphNode #719

Merged
merged 12 commits into from
Apr 5, 2023
29 changes: 29 additions & 0 deletions xray/services/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package services

import (
"encoding/json"
"github.com/jfrog/gofrog/datastructures"
"github.com/jfrog/jfrog-client-go/utils/log"
"net/http"
"strings"
Expand Down Expand Up @@ -189,6 +190,34 @@ type GraphNode struct {
Parent *GraphNode `json:"-"`
}

// FlattenGraph creates a set of dependencies from the given graph, and a map of the paths to each dependency.
func FlattenGraph(graph []*GraphNode) []*GraphNode {
flatGraph := []*GraphNode{}
depsSet := datastructures.MakeSet[string]()
for _, node := range graph {
flatGraph = append(flatGraph, getUniqueDependencies(node, depsSet)...)
}
return []*GraphNode{{Id: "root", Nodes: flatGraph}}
}

func getUniqueDependencies(node *GraphNode, depsSet *datastructures.Set[string]) []*GraphNode {
omerzi marked this conversation as resolved.
Show resolved Hide resolved
uniqueDeps := []*GraphNode{}
// Append current node
if !depsSet.Exists(node.Id) {
uniqueDeps = append(uniqueDeps, &GraphNode{Id: node.Id})
depsSet.Add(node.Id)
}
// Append current node children
for _, dependency := range node.Nodes {
if !depsSet.Exists(dependency.Id) {
depsSet.Add(dependency.Id)
uniqueDeps = append(uniqueDeps, &GraphNode{Id: dependency.Id})
uniqueDeps = append(uniqueDeps, getUniqueDependencies(dependency, depsSet)...)
}
}
return uniqueDeps
}

type OtherComponentIds struct {
Id string `json:"component_id,omitempty"`
Origin int `json:"origin,omitempty"`
Expand Down
31 changes: 31 additions & 0 deletions xray/services/scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package services

import (
"fmt"
"github.com/jfrog/gofrog/datastructures"
"github.com/stretchr/testify/assert"
"testing"
)

Expand Down Expand Up @@ -47,3 +49,32 @@ func TestCreateScanGraphQueryParams(t *testing.T) {
})
}
}

func TestFlattenGraph(t *testing.T) {
omerzi marked this conversation as resolved.
Show resolved Hide resolved
nodeA := &GraphNode{Id: "A"}
nodeB := &GraphNode{Id: "B"}
nodeC := &GraphNode{Id: "C"}
nodeD := &GraphNode{Id: "D"}
nodeE := &GraphNode{Id: "E"}
nodeF := &GraphNode{Id: "F"}

// Set dependencies
nodeA.Nodes = []*GraphNode{nodeB, nodeC}
nodeB.Nodes = []*GraphNode{nodeC, nodeD}
nodeC.Nodes = []*GraphNode{nodeD}
nodeD.Nodes = []*GraphNode{nodeE, nodeF}
nodeF.Nodes = []*GraphNode{nodeA, nodeB, nodeC}

// Create graph
graph := []*GraphNode{nodeA, nodeB, nodeC}
flatGraph := FlattenGraph(graph)

// Check that the graph has been flattened correctly
assert.Equal(t, len(flatGraph[0].Nodes), 6)
set := datastructures.MakeSet[string]()
for _, node := range flatGraph[0].Nodes {
assert.Len(t, node.Nodes, 0)
assert.False(t, set.Exists(node.Id))
set.Add(node.Id)
}
}