Skip to content

Commit

Permalink
Implement search dependent packages + testing (updated) (#969)
Browse files Browse the repository at this point in the history
* adding files

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* simplifying tests

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* making public

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* fixing

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* fixing errors in test

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* renaming files

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* casing in patchPlanning

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* fixing unsued

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* formatting

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* changes

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* removing variables

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* small fixes

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* generalizing

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* simplify tests

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* ingest seperated in tests

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* adding comments to test

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* resolving comments

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* small

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* changing bac

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* changing casing

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* fixing error

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* removing print statenment

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* fixing

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* fixinf error with ingesting on git

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* fixing

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* error fixing

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* testing if old version passes tests

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* reverting revert

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* trying to fix ingestion

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* trying old commit

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* changing back

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* trying small test case

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* changing ingestion to align with new PR

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* adding more description error message

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* resolving PR comments

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* adding extra switch to case

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* fixing the switch

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* removing global variables

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* fixing nit

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* changing comments

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* changing q

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* fixing tests

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* working tests

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* fixing lint

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* resolving lint

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* fixing pointer optional

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* adding to a comment

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

* resolving  nits

Signed-off-by: Rebecca Metzman <rmetzman@google.com>

---------

Signed-off-by: Rebecca Metzman <rmetzman@google.com>
Co-authored-by: Rebecca Metzman <rmetzman@google.com>
  • Loading branch information
rmetzman and Rebecca Metzman committed Jul 7, 2023
1 parent 2046ab7 commit 952bdac
Show file tree
Hide file tree
Showing 2 changed files with 677 additions and 0 deletions.
192 changes: 192 additions & 0 deletions pkg/guacanalytics/patchPlanning.go
@@ -0,0 +1,192 @@
//
// Copyright 2023 The GUAC Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package guacanalytics

import (
"context"
"fmt"

"github.com/Khan/genqlient/graphql"
model "github.com/guacsec/guac/pkg/assembler/clients/generated"
"github.com/guacsec/guac/pkg/misc/depversion"
)

type DfsNode struct {
Expanded bool // true once all node neighbors are added to queue
Parent string
Depth int
NodeType string // packageName, packageVersion
nodeVersions []string // for a packageName, what was the packageVersion associated with this version
}

type queueValues struct {
nodeMap map[string]DfsNode
now string
nowNode DfsNode
queue []string
}

// TODO: make more robust using predicates
func SearchDependenciesFromStartNode(ctx context.Context, gqlclient graphql.Client, startID string, stopID *string, maxDepth int) (map[string]DfsNode, error) {
startNode, err := model.Node(ctx, gqlclient, startID)

if err != nil {
return nil, fmt.Errorf("failed getting intial node with given ID:%w", err)
}

nodePkg, ok := startNode.Node.(*model.NodeNodePackage)

if !ok {
return nil, fmt.Errorf("Not a package")
}

q := queueValues{
queue: make([]string, 0), // the queue of nodes in bfs
nodeMap: map[string]DfsNode{},
}

// TODO: add functionality to start with other nodes?
if len(nodePkg.AllPkgTree.Namespaces) < 1 {
return nil, fmt.Errorf("Start by inputting a packageName or packageVerion node")
}

if len(nodePkg.AllPkgTree.Namespaces[0].Names) < 1 {
return nil, fmt.Errorf("Start by inputting a packageName or packageVerion node")
}

if len(nodePkg.AllPkgTree.Namespaces[0].Names[0].Versions) < 1 {
// TODO: handle case where there are circular depedencies that introduce more versions to the version list on a node that requires revisiting
var versionsList []string
for _, versionEntry := range nodePkg.AllPkgTree.Namespaces[0].Names[0].Versions {
versionsList = append(versionsList, versionEntry.Version)
}
q.nodeMap[startID] = DfsNode{
NodeType: "packageName",
nodeVersions: versionsList,
}
} else {
q.nodeMap[startID] = DfsNode{
NodeType: "packageVersion",
}

// Add packageName node to the frontier as well
q.queue = append(q.queue, nodePkg.AllPkgTree.Namespaces[0].Names[0].Id)

var versionsList []string
versionsList = append(versionsList, nodePkg.AllPkgTree.Namespaces[0].Names[0].Versions[0].Version)
q.nodeMap[nodePkg.AllPkgTree.Namespaces[0].Names[0].Id] = DfsNode{
NodeType: "packageName",
nodeVersions: versionsList,
}
}

q.queue = append(q.queue, startID)

for len(q.queue) > 0 {
q.now = q.queue[0]
q.queue = q.queue[1:]
q.nowNode = q.nodeMap[q.now]

if stopID != nil && *stopID == q.now {
break
}

if q.nowNode.Depth >= maxDepth {
break
}

neighborsResponse, err := model.Neighbors(ctx, gqlclient, q.now, []model.Edge{})

if err != nil {
return nil, fmt.Errorf("failed getting neighbors:%w", err)
}

for _, neighbor := range neighborsResponse.Neighbors {
err = caseOnPredicates(ctx, gqlclient, &q, neighbor, q.nowNode.NodeType)

if err != nil {
return nil, err
}
}

q.nowNode.Expanded = true
q.nodeMap[q.now] = q.nowNode
}

return q.nodeMap, nil

}

func caseOnPredicates(ctx context.Context, gqlclient graphql.Client, q *queueValues, neighbor model.NeighborsNeighborsNode, nodeType string) error {
// case on predicates and nodeType
switch nodeType {
case "packageName":
switch neighbor := neighbor.(type) {
case *model.NeighborsNeighborsIsDependency:
err := exploreIsDependencyFromDepPkg(ctx, gqlclient, q, *neighbor)

if err != nil {
return err
}
}
}

return nil
}

func exploreIsDependencyFromDepPkg(ctx context.Context, gqlclient graphql.Client, q *queueValues, isDependency model.NeighborsNeighborsIsDependency) error {
doesRangeInclude, err := depversion.DoesRangeInclude(q.nowNode.nodeVersions, isDependency.VersionRange)

if err != nil {
return err
}

if !doesRangeInclude {
return nil
}

dfsNVersion, seenVersion := q.nodeMap[isDependency.Package.Namespaces[0].Names[0].Versions[0].Id]
dfsNName, seenName := q.nodeMap[isDependency.Package.Namespaces[0].Names[0].Id]

if !seenVersion {
dfsNVersion = DfsNode{
Parent: q.now,
Depth: q.nowNode.Depth + 1,
NodeType: "packageVersion",
}
q.nodeMap[isDependency.Package.Namespaces[0].Names[0].Versions[0].Id] = dfsNVersion
}

if !seenName {
dfsNName = DfsNode{
Parent: q.now,
Depth: q.nowNode.Depth + 1,
NodeType: "packageName",
nodeVersions: []string{isDependency.Package.Namespaces[0].Names[0].Versions[0].Version},
}
q.nodeMap[isDependency.Package.Namespaces[0].Names[0].Id] = dfsNName
}

if !dfsNVersion.Expanded {
q.queue = append(q.queue, isDependency.Package.Namespaces[0].Names[0].Versions[0].Id)
}

if !dfsNName.Expanded {
q.queue = append(q.queue, isDependency.Package.Namespaces[0].Names[0].Id)
}

return nil
}

0 comments on commit 952bdac

Please sign in to comment.