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/find-bad-imports.ts
6465 views
1
import { DenoInfoDependency, Edge, getDenoInfo } from "./deno-info.ts";
2
import { brightBlue } from "jsr:/@std/fmt@^0.224.0/colors";
3
import { longestCommonDirPrefix } from "./utils.ts";
4
5
const allowedTerminalFileSuffixes = [
6
"types.ts",
7
"constants.ts",
8
"schemas.ts",
9
".json",
10
];
11
12
function isBadImport(source: string, dep: DenoInfoDependency) {
13
if (!(dep.code && dep.code.specifier)) {
14
if (
15
dep.type && dep.type.error &&
16
dep.type.error.startsWith("Relative import path") &&
17
source.indexOf("src/core/lib") !== -1 &&
18
!allowedTerminalFileSuffixes.some((allowedSuffix) =>
19
dep.type!.specifier!.endsWith(allowedSuffix)
20
)
21
) {
22
// report library imports from inside src/core/lib
23
return true;
24
} else {
25
return false;
26
}
27
}
28
const target = dep.code.specifier;
29
if (
30
allowedTerminalFileSuffixes.some((allowedSuffix) =>
31
target.endsWith(allowedSuffix)
32
)
33
) {
34
return false;
35
}
36
if (
37
source.indexOf("src/core/") !== -1 &&
38
target.indexOf("src/core/") === -1
39
) {
40
// report src/core imports to outside src/core
41
return true;
42
}
43
if (
44
source.indexOf("src/core/lib") !== -1 &&
45
target.indexOf("src/core/lib") === -1
46
) {
47
// report src/core/lib imports to outside src/core/lib
48
return true;
49
}
50
return false;
51
}
52
53
if (import.meta.main) {
54
const json = await getDenoInfo(Deno.args[0]);
55
const result: Edge[] = [];
56
const strs: string[] = [];
57
for (const mod of json.modules) {
58
const source = mod.specifier;
59
for (const dep of mod.dependencies || []) {
60
if (isBadImport(source, dep)) {
61
if (dep.code) {
62
result.push({ "from": source, to: dep.code.specifier! });
63
strs.push(source, dep.code.specifier!);
64
} else if (dep.type) {
65
result.push({ "from": source, to: dep.type.specifier! });
66
strs.push(source, dep.type.specifier!);
67
} else {
68
throw new Error(
69
"don't know how to handle a dependency decl without code or type",
70
);
71
}
72
}
73
}
74
}
75
const p = longestCommonDirPrefix(strs).length;
76
for (const { "from": edgeFrom, to } of result) {
77
console.log(
78
`Bad import from ${brightBlue(edgeFrom.slice(p))} to ${
79
brightBlue(to.slice(p))
80
}`,
81
);
82
}
83
}
84
85