Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/package/src/common/import-report/report-risky-files.ts
6453 views
1
import { resolve, toFileUrl } from "../../../../src/deno_ral/path.ts";
2
import {
3
DependencyGraph,
4
Edge,
5
getDenoInfo,
6
graphTranspose,
7
moduleGraph,
8
reachability,
9
} from "./deno-info.ts";
10
11
import { longestCommonDirPrefix } from "./utils.ts";
12
13
function filesInCycles(
14
graph: DependencyGraph,
15
): string[] {
16
const nodesInCycles: string[] = [];
17
18
const transpose = graphTranspose(graph);
19
const visited: Set<string> = new Set();
20
21
for (const source of Object.keys(graph)) {
22
const deps = reachability(graph, source);
23
if (!deps[source]) {
24
continue;
25
}
26
const inner = (node: string) => {
27
if (visited.has(node)) {
28
return;
29
}
30
visited.add(node);
31
for (const pred of transpose[node]) {
32
if (deps[pred].has(source) || pred === source) {
33
if (nodesInCycles.indexOf(node) === -1) {
34
nodesInCycles.push(node);
35
}
36
inner(pred);
37
}
38
}
39
};
40
inner(source);
41
}
42
return nodesInCycles;
43
}
44
45
if (import.meta.main) {
46
if (Deno.args.length === 0) {
47
console.log(
48
`report-risky-files.ts: Report files that are in import cycles and export constants
49
50
Usage:
51
$ quarto run --dev report-risky-files.ts <entry-point.ts>
52
53
Example:
54
$ quarto run --dev package/src/common/import-report/report-risky-files.ts src/quarto.ts`,
55
);
56
Deno.exit(1);
57
}
58
const json = await getDenoInfo(Deno.args[0]);
59
const { graph } = moduleGraph(json);
60
61
const rawCycleFiles = filesInCycles(graph);
62
63
const cmd = ["rg", "-l", "export const"];
64
const p = Deno.run({ cmd, stdout: "piped", stderr: "piped" });
65
const { code } = await p.status();
66
if (code !== 0) {
67
Deno.exit(code);
68
}
69
70
// heuristically remove string path prefixes
71
const cycleFiles = rawCycleFiles.map((s) =>
72
s.slice(rawCycleFiles[0].indexOf("/src/") + 5)
73
);
74
75
const exportFiles = new Set(
76
(new TextDecoder().decode(await p.output())).trim()
77
.split("\n"),
78
);
79
80
const result = cycleFiles.filter((s) => exportFiles.has(s));
81
result.sort((a, b) => a.localeCompare(b));
82
for (const r of result) {
83
console.log(r);
84
}
85
}
86
87