knip
Version:
Find and fix unused dependencies, exports and files in your TypeScript and JavaScript projects
113 lines (112 loc) • 5.96 kB
JavaScript
import { main } from './index.js';
import { perfObserver } from './util/Performance.js';
import parsedArgValues, { helpText } from './util/cli-arguments.js';
import { getKnownError, isConfigurationError, isDisplayReason, isKnownError } from './util/errors.js';
import { logError, logWarning } from './util/log.js';
import { cwd, join, toPosix } from './util/path.js';
import { runPreprocessors, runReporters } from './util/reporter.js';
import { prettyMilliseconds } from './util/string.js';
import { splitTags } from './util/tag.js';
import { isTrace } from './util/trace.js';
import { version } from './version.js';
const defaultCacheLocation = join(cwd, 'node_modules', '.cache', 'knip');
const { 'allow-remove-files': isRemoveFiles = false, cache: isCache = false, 'cache-location': cacheLocation = defaultCacheLocation, debug: isDebug = false, dependencies: isDependenciesShorthand = false, exclude: excludedIssueTypes = [], 'experimental-tags': experimentalTags = [], exports: isExportsShorthand = false, files: isFilesShorthand = false, fix: isFix = false, format: isFormat = false, 'fix-type': fixTypes = [], help: isHelp, include: includedIssueTypes = [], 'include-entry-exports': isIncludeEntryExports = false, 'include-libs': isIncludeLibs = false, 'isolate-workspaces': isIsolateWorkspaces = false, 'max-issues': maxIssues = '0', 'memory-realtime': memoryRealtime = false, 'no-config-hints': isNoConfigHints = false, 'no-exit-code': noExitCode = false, 'no-gitignore': isNoGitIgnore = false, 'no-progress': isNoProgress = isDebug || isTrace || memoryRealtime, preprocessor = [], 'preprocessor-options': preprocessorOptions = '', production: isProduction = false, reporter = ['symbols'], 'reporter-options': reporterOptions = '', strict: isStrict = false, tags = [], 'treat-config-hints-as-errors': treatConfigHintsAsErrors = false, tsConfig, version: isVersion, watch: isWatch = false, workspace: rawWorkspaceArg, } = parsedArgValues;
if (isHelp) {
console.log(helpText);
process.exit(0);
}
if (isVersion) {
console.log(version);
process.exit(0);
}
const isShowProgress = isNoProgress === false && process.stdout.isTTY && typeof process.stdout.cursorTo === 'function';
const workspace = rawWorkspaceArg ? toPosix(rawWorkspaceArg).replace(/^\.\//, '').replace(/\/$/, '') : undefined;
const run = async () => {
try {
const { report, issues, counters, rules, tagHints, configurationHints, isTreatConfigHintsAsErrors, includedWorkspaces, } = await main({
cacheLocation,
cwd,
excludedIssueTypes,
fixTypes: fixTypes.flatMap(type => type.split(',')),
gitignore: !isNoGitIgnore,
includedIssueTypes,
isCache,
isDebug,
isDependenciesShorthand,
isExportsShorthand,
isFilesShorthand,
isFix: isFix || fixTypes.length > 0,
isFormat,
isIncludeEntryExports,
isIncludeLibs,
isIsolateWorkspaces,
isProduction: isStrict || isProduction,
isRemoveFiles,
isShowProgress,
isStrict,
isWatch,
tags: tags.length > 0 ? splitTags(tags) : splitTags(experimentalTags),
tsConfigFile: tsConfig,
workspace,
});
const isDisableConfigHints = isNoConfigHints || isProduction || Boolean(workspace);
if (isWatch || isTrace)
return;
const initialData = {
report,
issues,
counters,
tagHints,
configurationHints,
isDisableConfigHints,
isTreatConfigHintsAsErrors,
cwd,
isProduction,
isShowProgress,
options: reporterOptions,
preprocessorOptions,
includedWorkspaces,
};
const finalData = await runPreprocessors(preprocessor, initialData);
await runReporters(reporter, finalData);
const totalErrorCount = Object.keys(finalData.report)
.filter(reportGroup => finalData.report[reportGroup] && rules[reportGroup] === 'error')
.reduce((errorCount, reportGroup) => errorCount + finalData.counters[reportGroup], 0);
if (perfObserver.isEnabled)
await perfObserver.finalize();
if (perfObserver.isTimerifyFunctions)
console.log(`\n${perfObserver.getTimerifiedFunctionsTable()}`);
if (perfObserver.isMemoryUsageEnabled && !memoryRealtime)
console.log(`\n${perfObserver.getMemoryUsageTable()}`);
if (perfObserver.isEnabled) {
const duration = perfObserver.getCurrentDurationInMs();
console.log('\nTotal running time:', prettyMilliseconds(duration));
perfObserver.reset();
}
if (experimentalTags.length > 0) {
logWarning('DEPRECATION WARNING', '--experimental-tags is deprecated, please start using --tags instead');
}
if (isIsolateWorkspaces && report.classMembers) {
logWarning('WARNING', 'Class members are not tracked when using the --isolate-workspaces flag');
}
if ((!noExitCode && totalErrorCount > Number(maxIssues)) ||
((treatConfigHintsAsErrors || isTreatConfigHintsAsErrors) && configurationHints.size > 0)) {
process.exit(1);
}
}
catch (error) {
process.exitCode = 2;
if (!isDebug && error instanceof Error && isKnownError(error)) {
const knownError = getKnownError(error);
logError('ERROR', knownError.message);
if (isDisplayReason(knownError))
console.error('Reason:', knownError.cause.message);
if (isConfigurationError(knownError))
console.log('\nRun `knip --help` or visit https://knip.dev for help');
process.exit(2);
}
throw error;
}
process.exit(0);
};
await run();