Path: blob/main/package/src/common/import-report/report-risky-files.ts
6453 views
import { resolve, toFileUrl } from "../../../../src/deno_ral/path.ts";1import {2DependencyGraph,3Edge,4getDenoInfo,5graphTranspose,6moduleGraph,7reachability,8} from "./deno-info.ts";910import { longestCommonDirPrefix } from "./utils.ts";1112function filesInCycles(13graph: DependencyGraph,14): string[] {15const nodesInCycles: string[] = [];1617const transpose = graphTranspose(graph);18const visited: Set<string> = new Set();1920for (const source of Object.keys(graph)) {21const deps = reachability(graph, source);22if (!deps[source]) {23continue;24}25const inner = (node: string) => {26if (visited.has(node)) {27return;28}29visited.add(node);30for (const pred of transpose[node]) {31if (deps[pred].has(source) || pred === source) {32if (nodesInCycles.indexOf(node) === -1) {33nodesInCycles.push(node);34}35inner(pred);36}37}38};39inner(source);40}41return nodesInCycles;42}4344if (import.meta.main) {45if (Deno.args.length === 0) {46console.log(47`report-risky-files.ts: Report files that are in import cycles and export constants4849Usage:50$ quarto run --dev report-risky-files.ts <entry-point.ts>5152Example:53$ quarto run --dev package/src/common/import-report/report-risky-files.ts src/quarto.ts`,54);55Deno.exit(1);56}57const json = await getDenoInfo(Deno.args[0]);58const { graph } = moduleGraph(json);5960const rawCycleFiles = filesInCycles(graph);6162const cmd = ["rg", "-l", "export const"];63const p = Deno.run({ cmd, stdout: "piped", stderr: "piped" });64const { code } = await p.status();65if (code !== 0) {66Deno.exit(code);67}6869// heuristically remove string path prefixes70const cycleFiles = rawCycleFiles.map((s) =>71s.slice(rawCycleFiles[0].indexOf("/src/") + 5)72);7374const exportFiles = new Set(75(new TextDecoder().decode(await p.output())).trim()76.split("\n"),77);7879const result = cycleFiles.filter((s) => exportFiles.has(s));80result.sort((a, b) => a.localeCompare(b));81for (const r of result) {82console.log(r);83}84}858687