knip
Version:
Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects
96 lines (95 loc) • 3.9 kB
JavaScript
import { watch } from 'node:fs';
import { CatalogCounselor } from "./CatalogCounselor.js";
import { ConfigurationChief } from "./ConfigurationChief.js";
import { ConsoleStreamer } from "./ConsoleStreamer.js";
import { DependencyDeputy } from "./DependencyDeputy.js";
import { analyze } from "./graph/analyze.js";
import { build } from "./graph/build.js";
import { IssueCollector } from "./IssueCollector.js";
import { ProjectPrincipal } from "./ProjectPrincipal.js";
import watchReporter from "./reporters/watch.js";
import { debugLogObject } from "./util/debug.js";
import { getGitIgnoredHandler } from "./util/glob-core.js";
import { getModuleSourcePathHandler } from "./util/to-source-path.js";
import { getSessionHandler } from "./util/watch.js";
export const run = async (options) => {
debugLogObject('*', 'Unresolved configuration', options);
debugLogObject('*', 'Included issue types', options.includedIssueTypes);
const chief = new ConfigurationChief(options);
const deputy = new DependencyDeputy(options);
const streamer = new ConsoleStreamer(options);
const collector = new IssueCollector(options);
const counselor = new CatalogCounselor(options);
streamer.cast('Reading workspace configuration');
const workspaces = await chief.getWorkspaces();
const isGitIgnored = await getGitIgnoredHandler(options, new Set(workspaces.map(w => w.dir)));
const toSourceFilePath = getModuleSourcePathHandler(chief);
const principal = new ProjectPrincipal(options, toSourceFilePath);
collector.setWorkspaceFilter(chief.workspaceFilePathFilter);
collector.setIgnoreIssues(chief.config.ignoreIssues);
debugLogObject('*', 'Included workspaces', () => workspaces.map(w => w.pkgName));
debugLogObject('*', 'Included workspace configs', () => workspaces.map(w => ({ pkgName: w.pkgName, name: w.name, config: w.config, ancestors: w.ancestors })));
const { graph, entryPaths, analyzedFiles, unreferencedFiles, analyzeSourceFile, enabledPluginsStore } = await build({
chief,
collector,
counselor,
deputy,
principal,
isGitIgnored,
streamer,
workspaces,
options,
});
const reAnalyze = await analyze({
analyzedFiles,
counselor,
chief,
collector,
deputy,
entryPaths,
graph,
streamer,
unreferencedFiles,
options,
});
let session;
if (options.isWatch || options.isSession) {
const isIgnored = (filePath) => (!!options.cacheLocation && filePath.startsWith(options.cacheLocation)) ||
filePath.includes('/.git/') ||
isGitIgnored(filePath);
const onFileChange = options.isWatch
? ({ issues, duration }) => watchReporter(options, { issues, streamer, size: analyzedFiles.size, duration })
: undefined;
session = await getSessionHandler(options, {
analyzedFiles,
analyzeSourceFile,
chief,
collector,
analyze: reAnalyze,
principal,
graph,
isIgnored,
onFileChange,
unreferencedFiles,
entryPaths,
});
if (options.isWatch)
watch('.', { recursive: true }, session.listener);
}
const { issues, counters, tagHints, configurationHints } = collector.getIssues();
if (!options.isWatch)
streamer.clear();
return {
results: {
issues,
counters,
tagHints,
configurationHints,
selectedWorkspaces: chief.selectedWorkspaces ? Array.from(chief.selectedWorkspaces) : undefined,
includedWorkspaceDirs: Array.from(chief.workspacesByDir.keys()),
enabledPlugins: Object.fromEntries(enabledPluginsStore),
},
session,
streamer,
};
};