tutanota/buildSrc/graph.js

86 lines
1.9 KiB
JavaScript
Raw Permalink Normal View History

import fs from "node:fs"
2019-09-13 13:49:11 +02:00
function toDot(modules, output) {
let buffer = "digraph G {\n"
buffer += "edge [dir=back]\n"
2023-09-07 17:56:39 +02:00
for (const m of modules) {
for (const dep of m.deps) {
2021-02-03 17:13:38 +01:00
buffer += `"${dep}" -> "${m.id}"\n`
2023-09-07 17:56:39 +02:00
}
}
2019-09-13 13:49:11 +02:00
buffer += "}\n"
2022-12-27 15:37:40 +01:00
fs.writeFileSync(output, buffer, { encoding: "utf8" })
2019-09-13 13:49:11 +02:00
}
function prune(modules) {
2022-12-27 15:37:40 +01:00
let avail = modules.filter((m) => m.deps.length == 0)
2019-09-13 13:49:11 +02:00
if (!avail.length) {
2022-12-27 15:37:40 +01:00
return
2019-09-13 13:49:11 +02:00
}
2022-12-27 15:37:40 +01:00
let id = avail[0].id
// console.log("pruning", id);
let index = modules.indexOf(avail[0])
modules.splice(index, 1)
2023-09-07 17:56:39 +02:00
for (const m of modules) {
2022-12-27 15:37:40 +01:00
m.deps = m.deps.filter((dep) => dep != id)
2023-09-07 17:56:39 +02:00
}
2022-12-27 15:37:40 +01:00
prune(modules)
2019-09-13 13:49:11 +02:00
}
function getPrefix(ids) {
if (ids.length < 2) {
2022-12-27 15:37:40 +01:00
return ""
2019-09-13 13:49:11 +02:00
}
return ids.reduce((prefix, val) => {
while (val.indexOf(prefix) != 0) {
2022-12-27 15:37:40 +01:00
prefix = prefix.substring(0, prefix.length - 1)
2019-09-13 13:49:11 +02:00
}
2022-12-27 15:37:40 +01:00
return prefix
})
2019-09-13 13:49:11 +02:00
}
/**
* Plugin which will generate .dot file with dependency graph
* @param options {{exclude: string, output: string, prune: boolean, prefix: string}}
2019-09-13 13:49:11 +02:00
*/
export default function plugin(options) {
2022-12-27 15:37:40 +01:00
let exclude = (str) => options.exclude && str.match(options.exclude)
2019-09-13 13:49:11 +02:00
let output = options.output
if (!output) throw new Error("Please specify output file")
return {
generateBundle(bundleOptions, bundle, isWrite) {
2022-12-27 15:37:40 +01:00
let ids = []
2019-09-13 13:49:11 +02:00
for (const moduleId of this.moduleIds) {
if (!exclude(moduleId)) {
2022-12-27 15:37:40 +01:00
ids.push(moduleId)
2019-09-13 13:49:11 +02:00
}
}
2022-12-27 15:37:40 +01:00
let prefix = options.prefix || getPrefix(ids)
let strip = (str) => (str.startsWith(prefix) ? str.substring(prefix.length) : str)
2019-09-13 13:49:11 +02:00
2022-12-27 15:37:40 +01:00
let modules = []
2023-09-07 17:56:39 +02:00
for (const id of ids) {
2019-09-13 13:49:11 +02:00
let m = {
id: strip(id),
2022-12-27 15:37:40 +01:00
deps: this.getModuleInfo(id)
.importedIds.filter((x) => !exclude(x))
.concat(this.getModuleInfo(id).dynamicImporters.filter((x) => !exclude(x)))
.map(strip),
2019-09-13 13:49:11 +02:00
}
if (exclude(m.id)) {
2023-09-07 17:56:39 +02:00
continue
2019-09-13 13:49:11 +02:00
}
2022-12-27 15:37:40 +01:00
modules.push(m)
2023-09-07 17:56:39 +02:00
}
2019-09-13 13:49:11 +02:00
if (options.prune) {
2022-12-27 15:37:40 +01:00
prune(modules)
2019-09-13 13:49:11 +02:00
}
2022-12-27 15:37:40 +01:00
toDot(modules, output)
},
2019-09-13 13:49:11 +02:00
}
2022-12-27 15:37:40 +01:00
}