Skip to content

Commit c60d332

Browse files
authored
Merge pull request #14 from snyk/feat/to-legacy-tree
Convert to legacy format
2 parents dd4f30a + caef817 commit c60d332

16 files changed

+6810
-1529
lines changed

src/legacy/index.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { DepGraphBuilder } from '../core/builder';
55

66
export {
77
depTreeToGraph,
8+
graphToDepTree,
89
DepTree,
910
};
1011

@@ -17,6 +18,7 @@ interface DepTreeDep {
1718
}
1819

1920
interface DepTree extends DepTreeDep {
21+
packageFormatVersion?: string;
2022
targetOS?: {
2123
name: string;
2224
version: string;
@@ -152,6 +154,77 @@ async function shortenNodeIds(depGraph: types.DepGraphInternal): Promise<types.D
152154
return builder.build();
153155
}
154156

157+
async function graphToDepTree(depGraphInterface: types.DepGraph, pkgType: string): Promise<DepTree> {
158+
const depGraph = (depGraphInterface as types.DepGraphInternal);
159+
160+
// TODO: implement cycles support
161+
if (depGraph.hasCycles()) {
162+
throw new Error('Conversion to DepTree does not support cyclic graphs yet');
163+
}
164+
165+
const depTree = await buildSubtree(depGraph, depGraph.rootNodeId);
166+
167+
depTree.packageFormatVersion = constructPackageFormatVersion(pkgType);
168+
169+
const targetOS = constructTargetOS(depGraph);
170+
if (targetOS) {
171+
depTree.targetOS = targetOS;
172+
}
173+
174+
return depTree;
175+
}
176+
177+
function constructPackageFormatVersion(pkgType: string): string {
178+
if (pkgType === 'maven') {
179+
pkgType = 'mvn';
180+
}
181+
return `${pkgType}:0.0.1`;
182+
}
183+
184+
function constructTargetOS(depGraph: types.DepGraph): { name: string; version: string; } {
185+
if (['apk', 'apt', 'deb', 'rpm'].indexOf(depGraph.pkgManager.name) === -1) {
186+
// .targetOS is undefined unless its a linux pkgManager
187+
return;
188+
}
189+
190+
if (!depGraph.pkgManager.repositories
191+
|| !depGraph.pkgManager.repositories.length
192+
|| !depGraph.pkgManager.repositories[0].alias) {
193+
throw new Error('Incomplete .pkgManager, could not create .targetOS');
194+
}
195+
196+
const [name, version] = depGraph.pkgManager.repositories[0].alias.split(':');
197+
return { name, version };
198+
}
199+
200+
async function buildSubtree(depGraph: types.DepGraphInternal, nodeId: string): Promise<DepTree> {
201+
const nodePkg = depGraph.getNodePkg(nodeId);
202+
const depTree: DepTree = {};
203+
depTree.name = nodePkg.name;
204+
depTree.version = nodePkg.version;
205+
206+
const depInstanceIds = depGraph.getNodeDepsNodeIds(nodeId);
207+
if (!depInstanceIds || depInstanceIds.length === 0) {
208+
return depTree;
209+
}
210+
211+
for (const depInstId of depInstanceIds) {
212+
const subtree = await buildSubtree(depGraph, depInstId);
213+
if (!subtree) {
214+
continue;
215+
}
216+
217+
if (!depTree.dependencies) {
218+
depTree.dependencies = {};
219+
}
220+
221+
depTree.dependencies[subtree.name] = subtree;
222+
}
223+
224+
await spinTheEventLoop();
225+
return depTree;
226+
}
227+
155228
async function spinTheEventLoop() {
156229
return new Promise((resolve) => setImmediate(resolve));
157230
}

test/fixtures/cyclic-dep-graph.json

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"schemaVersion": "1.0.0",
3+
"pkgManager": {
4+
"name": "pip"
5+
},
6+
"pkgs": [
7+
{
8+
9+
"info": {
10+
"name": "toor",
11+
"version": "1.0.0"
12+
}
13+
},
14+
{
15+
"id": "foo@2",
16+
"info": {
17+
"name": "foo",
18+
"version": "2"
19+
}
20+
},
21+
{
22+
"id": "bar@3",
23+
"info": {
24+
"name": "bar",
25+
"version": "3"
26+
}
27+
},
28+
{
29+
"id": "baz@4",
30+
"info": {
31+
"name": "baz",
32+
"version": "4"
33+
}
34+
}
35+
],
36+
"graph": {
37+
"rootNodeId": "toor",
38+
"nodes": [
39+
{
40+
"nodeId": "toor",
41+
"pkgId": "[email protected]",
42+
"deps": [
43+
{
44+
"nodeId": "foo@2|x"
45+
}
46+
]
47+
},
48+
{
49+
"nodeId": "foo@2|x",
50+
"pkgId": "foo@2",
51+
"deps": [
52+
{
53+
"nodeId": "bar@3|x"
54+
}
55+
]
56+
},
57+
{
58+
"nodeId": "bar@3|x",
59+
"pkgId": "bar@3",
60+
"deps": [
61+
{
62+
"nodeId": "baz@4|x"
63+
}
64+
]
65+
},
66+
{
67+
"nodeId": "baz@4|x",
68+
"pkgId": "baz@4",
69+
"deps": [
70+
{
71+
"nodeId": "foo@2|x"
72+
}
73+
]
74+
}
75+
]
76+
}
77+
}

0 commit comments

Comments
 (0)