Skip to content

Commit 2356867

Browse files
committed
chore: copy over types and builder from dep-graph-go
1 parent 6af74c1 commit 2356867

File tree

2 files changed

+277
-0
lines changed

2 files changed

+277
-0
lines changed

internal/depgraph/builder.go

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// TODO(uv): this is copied from the `dep-graph-go` library. We should open-source that code and import it here.
2+
package depgraph
3+
4+
import (
5+
"errors"
6+
"fmt"
7+
)
8+
9+
type Builder struct {
10+
schemaVersion string
11+
rootNodeID string
12+
rootPkgID string
13+
pkgManager *PkgManager
14+
pkgs map[string]*Pkg
15+
nodes map[string]*Node
16+
}
17+
18+
const (
19+
schemaVersion = "1.3.0"
20+
rootNodeID = "root-node"
21+
)
22+
23+
func NewBuilder(pkgManager *PkgManager, rootPkg *PkgInfo) (*Builder, error) {
24+
if pkgManager == nil {
25+
return nil, errors.New("cannot create builder without a package manager")
26+
}
27+
28+
if rootPkg == nil {
29+
rootPkg = &PkgInfo{
30+
Name: "_root",
31+
Version: "0.0.0",
32+
}
33+
}
34+
35+
b := &Builder{
36+
schemaVersion: schemaVersion,
37+
pkgManager: pkgManager,
38+
rootNodeID: rootNodeID,
39+
rootPkgID: getPkgID(rootPkg),
40+
pkgs: make(map[string]*Pkg),
41+
nodes: make(map[string]*Node),
42+
}
43+
44+
b.addNode(b.rootNodeID, rootPkg)
45+
46+
return b, nil
47+
}
48+
49+
func (b *Builder) Build() *DepGraph {
50+
dg := &DepGraph{
51+
SchemaVersion: b.schemaVersion,
52+
PkgManager: *b.pkgManager,
53+
Pkgs: b.GetPkgs(),
54+
rootPkg: b.pkgs[b.rootPkgID],
55+
pkgIdx: make(map[string]*Pkg),
56+
Graph: Graph{
57+
RootNodeID: b.rootNodeID,
58+
Nodes: make([]Node, 0, len(b.nodes)),
59+
},
60+
}
61+
62+
for nodeID, node := range b.nodes {
63+
pkg := b.pkgs[node.PkgID]
64+
dg.pkgIdx[pkg.ID] = pkg
65+
66+
dg.Graph.Nodes = append(dg.Graph.Nodes, Node{
67+
NodeID: nodeID,
68+
PkgID: node.PkgID,
69+
Deps: node.Deps,
70+
})
71+
}
72+
73+
return dg
74+
}
75+
76+
func (b *Builder) GetPkgManager() *PkgManager {
77+
return b.pkgManager
78+
}
79+
80+
func (b *Builder) GetPkgs() []Pkg {
81+
pkgs := make([]Pkg, 0, len(b.pkgs))
82+
83+
for _, pkgInfo := range b.pkgs {
84+
pkgs = append(pkgs, *pkgInfo)
85+
}
86+
87+
return pkgs
88+
}
89+
90+
func (b *Builder) GetRootNode() *Node {
91+
return b.nodes[b.rootNodeID]
92+
}
93+
94+
func (b *Builder) AddNode(nodeID string, pkgInfo *PkgInfo) *Node {
95+
return b.addNode(nodeID, pkgInfo)
96+
}
97+
98+
func (b *Builder) addNode(nodeID string, pkgInfo *PkgInfo) *Node {
99+
if n, ok := b.nodes[nodeID]; ok {
100+
return n
101+
}
102+
pkgID := getPkgID(pkgInfo)
103+
104+
b.pkgs[pkgID] = &Pkg{
105+
ID: pkgID,
106+
Info: *pkgInfo,
107+
}
108+
109+
b.nodes[nodeID] = &Node{
110+
NodeID: nodeID,
111+
PkgID: pkgID,
112+
Deps: make([]Dependency, 0),
113+
}
114+
115+
return b.nodes[nodeID]
116+
}
117+
118+
func (b *Builder) ConnectNodes(parentNodeID, childNodeID string) error {
119+
parentNode, ok := b.nodes[parentNodeID]
120+
if !ok {
121+
return fmt.Errorf("cound not find parent node %s", parentNodeID)
122+
}
123+
124+
childNode, ok := b.nodes[childNodeID]
125+
if !ok {
126+
return fmt.Errorf("cound not find child node %s", childNodeID)
127+
}
128+
129+
parentNode.Deps = append(parentNode.Deps, Dependency{
130+
NodeID: childNode.NodeID,
131+
})
132+
133+
return nil
134+
}
135+
136+
func getPkgID(pkgInfo *PkgInfo) string {
137+
return fmt.Sprintf("%s@%s", pkgInfo.Name, pkgInfo.Version)
138+
}

internal/depgraph/depgraph.go

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
// TODO(uv): this is copied from the `dep-graph-go` library. We should open-source that code and import it here.
2+
package depgraph
3+
4+
import (
5+
"bytes"
6+
"encoding/json"
7+
"fmt"
8+
)
9+
10+
type (
11+
DepGraph struct {
12+
SchemaVersion string `json:"schemaVersion"`
13+
PkgManager PkgManager `json:"pkgManager"`
14+
Pkgs []Pkg `json:"pkgs"`
15+
Graph Graph `json:"graph"`
16+
17+
rootPkg *Pkg `json:"-"`
18+
pkgIdx map[string]*Pkg `json:"-"`
19+
}
20+
21+
PkgManager struct {
22+
Name string `json:"name"`
23+
Version string `json:"version,omitempty"`
24+
Repositories []Repository `json:"repositories,omitempty"`
25+
}
26+
27+
Repository struct {
28+
Alias string `json:"alias"`
29+
}
30+
31+
Pkg struct {
32+
ID string `json:"id"`
33+
Info PkgInfo `json:"info"`
34+
}
35+
36+
PkgInfo struct {
37+
Name string `json:"name"`
38+
Version string `json:"version,omitempty"`
39+
PackageURL string `json:"purl,omitempty"`
40+
}
41+
42+
Graph struct {
43+
RootNodeID string `json:"rootNodeId"`
44+
Nodes []Node `json:"nodes"`
45+
}
46+
47+
Node struct {
48+
NodeID string `json:"nodeId"`
49+
PkgID string `json:"pkgId"`
50+
Info *NodeInfo `json:"info,omitempty"`
51+
Deps []Dependency `json:"deps"`
52+
}
53+
54+
NodeInfo struct {
55+
VersionProvenance *VersionProvenance `json:"versionProvenance,omitempty"`
56+
Labels map[string]string `json:"labels,omitempty"`
57+
}
58+
59+
Dependency struct {
60+
NodeID string `json:"nodeId"`
61+
}
62+
63+
VersionProvenance struct {
64+
Type string `json:"type"`
65+
Location string `json:"location"`
66+
Property *Property `json:"property,omitempty"`
67+
}
68+
69+
Property struct {
70+
Name string `json:"name"`
71+
}
72+
)
73+
74+
func New() *DepGraph {
75+
return &DepGraph{
76+
Pkgs: make([]Pkg, 0),
77+
Graph: Graph{
78+
Nodes: make([]Node, 0),
79+
},
80+
}
81+
}
82+
83+
func UnmarshalJSON(data []byte) (*DepGraph, error) {
84+
dg := new(DepGraph)
85+
dec := json.NewDecoder(bytes.NewReader(data))
86+
dec.DisallowUnknownFields()
87+
88+
if err := dec.Decode(&dg); err != nil {
89+
return nil, fmt.Errorf("could not decode DepGraph: %w", err)
90+
}
91+
92+
return dg, nil
93+
}
94+
95+
func (dg *DepGraph) MarshalJSON() ([]byte, error) {
96+
data, err := json.Marshal(*dg)
97+
if err != nil {
98+
return nil, fmt.Errorf("could not encode DepGraph: %w", err)
99+
}
100+
return data, nil
101+
}
102+
103+
func (dg *DepGraph) GetRootPkg() *Pkg {
104+
if dg.rootPkg != nil {
105+
return dg.rootPkg
106+
}
107+
108+
for _, dep := range dg.Graph.Nodes {
109+
if dep.NodeID != dg.Graph.RootNodeID {
110+
continue
111+
}
112+
113+
for _, pkg := range dg.Pkgs {
114+
if pkg.ID != dep.PkgID {
115+
continue
116+
}
117+
118+
dg.rootPkg = &pkg
119+
break
120+
}
121+
}
122+
123+
return dg.rootPkg
124+
}
125+
126+
func (dg *DepGraph) GetPkg(id string) (*Pkg, bool) {
127+
if dg.pkgIdx == nil {
128+
dg.pkgIdx = make(map[string]*Pkg)
129+
for _, pkg := range dg.Pkgs {
130+
dg.pkgIdx[pkg.ID] = &pkg
131+
}
132+
}
133+
134+
if pkg, ok := dg.pkgIdx[id]; ok {
135+
return pkg, ok
136+
}
137+
138+
return nil, false
139+
}

0 commit comments

Comments
 (0)