UNPKG

code-complexity

Version:

Measure the churn/complexity score. Higher values mean hotspots where refactorings should happen.

111 lines (110 loc) 4.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const node_child_process_1 = require("node:child_process"); const node_fs_1 = require("node:fs"); const node_path_1 = require("node:path"); const node_os_1 = require("node:os"); const node_url_1 = require("node:url"); const commander_1 = require("commander"); const utils_1 = require("../utils"); const internal = { debug: (0, utils_1.buildDebugger)("cli") }; exports.default = { parse, cleanup }; async function parse() { const { description, version } = await (0, utils_1.getPackageJson)(); const cli = getRawCli(description, version).parse(); assertArgsAreProvided(cli); const options = buildOptions(cli.args, cli.opts()); internal.debug(`applying options: ${JSON.stringify(options)}`); return options; } function cleanup(options) { if (options.target instanceof node_url_1.URL) { (0, node_child_process_1.execSync)(`rm -rf ${options.directory}`, { stdio: "ignore" }); } } function getRawCli(description, version) { return commander_1.program .name("code-complexity") .usage("<target> [options]") .argument("<target>") .version(version || "") .description(description || "") .option("--filter <strings>", "list of globs (comma separated) to filter", commaSeparatedList) .option("-cs, --complexity-strategy [sloc|cyclomatic|halstead]", "choose the complexity strategy to analyze your codebase with", /^(sloc|cyclomatic|halstead)$/i) .option("-f, --format [format]", "format results using table or json", /^(table|json|csv)$/i) .option("-l, --limit [limit]", "limit the number of files to output", parseInt) .option("-i, --since [since]", "limit analysis to commits more recent in age than date") .option("-u, --until [until]", "limit analysis to commits older in age than date") .option("-s, --sort [sort]", "sort results (allowed valued: score, churn, complexity or file)", /^(score|churn|complexity|file)$/i) .option("-d, --directories", "display values for directories instead of files") .on("--help", () => { console.log(); console.log("Examples:"); console.log(); [ "$ code-complexity .", "$ code-complexity https://github.com/simonrenoult/code-complexity", "$ code-complexity foo --limit 3", "$ code-complexity ../foo --sort score", "$ code-complexity /foo/bar --filter 'src/**,!src/front/**'", "$ code-complexity . --limit 10 --sort score", "$ code-complexity . --limit 10 --modules", "$ code-complexity . --limit 10 --sort score -cs halstead", "$ code-complexity . --since=2021-06-01 --limit 100", "$ code-complexity . --since=2021-04-01 --until=2021-07-01", ].forEach((example) => console.log(example.padStart(2))); }); } function buildOptions(args, options) { const target = parseTarget(args[0]); return { target, directory: parseDirectory(target), directories: options.directories, format: options.format ? String(options.format) : "table", filter: options.filter || [], limit: options.limit ? Number(options.limit) : undefined, since: options.since ? String(options.since) : undefined, until: options.until ? String(options.until) : undefined, sort: options.sort ? String(options.sort) : undefined, complexityStrategy: options.complexityStrategy ? String(options.complexityStrategy) : "sloc", }; // FIXME: I'm not a fan of pulling the code here but it's good enough. function parseDirectory(target) { if (target instanceof node_url_1.URL) { const temporaryDirLocation = (0, node_os_1.tmpdir)() + node_path_1.sep + `code-complexity-${new Date().getTime()}`; (0, node_child_process_1.execSync)(`git clone ${target} ${temporaryDirLocation}`, { stdio: "ignore", }); return temporaryDirLocation; } else { return target; } } function parseTarget(target) { try { return new node_url_1.URL(target); } catch (e) { try { (0, node_fs_1.lstatSync)(target); return target; } catch (e) { throw new Error("Argument 'target' is neither a directory nor a valid URL."); } } } } function commaSeparatedList(value) { return value.split(","); } function assertArgsAreProvided(internalCli) { if (!internalCli.args || !internalCli.args.length) { internalCli.help(); process.exit(1); } }