-
-
Notifications
You must be signed in to change notification settings - Fork 151
/
depgraph
executable file
·56 lines (50 loc) · 1.71 KB
/
depgraph
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#!/usr/bin/env node
const fs = require("fs");
const execSync = require('child_process').execSync;
const dg = require("@thi.ng/dgraph");
const tx = require("@thi.ng/transducers");
const baseDir = "./packages/";
const col = "#555555";
const ecol = "#aaaaaa";
const xform = tx.comp(
tx.map((f) => baseDir + f),
tx.filter((f) => f.indexOf(".DS_Store") < 0 && fs.statSync(f).isDirectory),
tx.map((f) => fs.readFileSync(f + "/package.json")),
tx.map((p) => {
p = JSON.parse(p.toString());
return {
id: p.name,
v: p.version,
deps: p.dependencies ? Object.keys(p.dependencies) : []
};
}));
const packages = tx.transduce(xform, tx.push(), fs.readdirSync(baseDir));
const formatted = tx.transduce(
tx.map((m) => `"${m.id}"[color="${col}",label="${m.id}\\n${m.v}"];\n` +
m.deps.map((d) => `"${m.id}" -> "${d}"[color="${ecol}"];`).join("\n")),
tx.str("\n"),
packages
);
const leaves = tx.transduce(
tx.comp(tx.filter((p) => !p.deps.length), tx.map((p) => `"${p.id}";`)),
tx.str(" "),
packages
);
const dot = `digraph g {
# size="16,9";
# ratio=fill;
rankdir=RL;
node[fontname=Inconsolata,fontsize=9,fontcolor=white,style=filled];
edge[arrowsize=0.66];
${formatted}
subgraph cluster0 { color="white"; rank=same; ${leaves} }
}`;
fs.writeFileSync("assets/deps.dot", dot, "utf8");
execSync("dot -Tpng -o assets/deps.png assets/deps.dot");
const g = new dg.DGraph();
tx.run(
tx.mapcat((p) => tx.tuples(tx.repeat(p.id), p.deps)),
([p, d]) => g.addDependency(p, d),
packages);
console.log("topo order:", g.sort().map((x) => x.replace("@thi.ng/", "")).join(" "));
console.log("done");