UNPKG

auto-cr-cmd

Version:

Fast automated code review CLI powered by SWC-based static analysis

253 lines (252 loc) 9.52 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.createReporter = createReporter; var auto_cr_rules_1 = require("auto-cr-rules"); var consola_1 = __importDefault(require("consola")); var i18n_1 = require("../i18n"); var UNTAGGED_TAG = 'untagged'; var DEFAULT_FORMAT = 'text'; var severityLoggers = (_a = {}, _a[auto_cr_rules_1.RuleSeverity.Error] = consola_1.default.error, _a[auto_cr_rules_1.RuleSeverity.Warning] = consola_1.default.warn, _a[auto_cr_rules_1.RuleSeverity.Optimizing] = consola_1.default.info, _a); function createReporter(filePath, source, options) { var _a; if (options === void 0) { options = {}; } var offsets = buildLineOffsets(source); var t = (0, i18n_1.getTranslator)(); var language = (0, i18n_1.getLanguage)(); var records = []; var format = (_a = options.format) !== null && _a !== void 0 ? _a : DEFAULT_FORMAT; var totalViolations = 0; var errorViolations = 0; var severityCounts = { error: 0, warning: 0, optimizing: 0, }; var pushRecord = function (record) { records.push(record); totalViolations += 1; if (record.severity === auto_cr_rules_1.RuleSeverity.Error) { errorViolations += 1; severityCounts.error += 1; } else if (record.severity === auto_cr_rules_1.RuleSeverity.Warning) { severityCounts.warning += 1; } else if (record.severity === auto_cr_rules_1.RuleSeverity.Optimizing) { severityCounts.optimizing += 1; } }; var error = function (message) { pushRecord({ tag: UNTAGGED_TAG, ruleName: 'general', severity: auto_cr_rules_1.RuleSeverity.Error, message: message, }); }; var errorAtLine = function (line, message) { pushRecord({ tag: UNTAGGED_TAG, ruleName: 'general', severity: auto_cr_rules_1.RuleSeverity.Error, line: line, message: message, }); }; var errorAtSpan = function (spanLike, message) { var span = extractSpan(spanLike); if (!span) { error(message); return; } var line = offsetToLine(span.start, offsets); errorAtLine(line, message); }; var buildRuleReporter = function (rule) { var _a, _b; var tag = (_a = rule.tag) !== null && _a !== void 0 ? _a : UNTAGGED_TAG; var severity = (_b = rule.severity) !== null && _b !== void 0 ? _b : auto_cr_rules_1.RuleSeverity.Error; var store = function (payload) { pushRecord({ tag: tag, ruleName: rule.name, severity: severity, message: payload.message, line: payload.line, code: payload.code, suggestions: payload.suggestions, }); }; var scopedError = function (message) { store({ message: message }); }; var scopedErrorAtLine = function (line, message) { store({ message: message, line: line }); }; var scopedErrorAtSpan = function (spanLike, message) { var span = extractSpan(spanLike); if (!span) { scopedError(message); return; } var line = offsetToLine(span.start, offsets); scopedErrorAtLine(line, message); }; var record = function (payload) { var line = resolveLine(payload, offsets); store({ message: payload.description, line: line, code: payload.code, suggestions: payload.suggestions, }); }; var reporterWithRecord = { error: scopedError, errorAtLine: scopedErrorAtLine, errorAtSpan: scopedErrorAtSpan, record: record, }; return reporterWithRecord; }; var flush = function () { var violationSnapshot = records.map(function (record) { return (__assign(__assign({}, record), { suggestions: record.suggestions ? __spreadArray([], record.suggestions, true) : undefined })); }); var summary = { totalViolations: totalViolations, errorViolations: errorViolations, severityCounts: { error: severityCounts.error, warning: severityCounts.warning, optimizing: severityCounts.optimizing, }, violations: violationSnapshot, }; if (violationSnapshot.length > 0 && format === 'text') { var locale = language === 'zh' ? 'zh-CN' : 'en-US'; var formatter_1 = new Intl.DateTimeFormat(locale, { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, }); var indent_1 = ' '; var colon_1 = language === 'zh' ? ':' : ':'; var headerGap_1 = language === 'zh' ? '' : ' '; violationSnapshot.forEach(function (violation) { var timestamp = formatter_1.format(new Date()); var tagLabel = t.ruleTagLabel({ tag: violation.tag }); var severityIcon = t.reporterSeverityIcon({ severity: violation.severity }); var logger = getLoggerForSeverity(violation.severity); var header = "[".concat(timestamp, "] ").concat(severityIcon, " [").concat(tagLabel, "]").concat(colon_1).concat(headerGap_1).concat(violation.ruleName); logger(header); var location = typeof violation.line === 'number' ? "".concat(filePath, ":").concat(violation.line) : filePath; consola_1.default.log("".concat(indent_1).concat(t.reporterFileLabel(), ": ").concat(location)); consola_1.default.log("".concat(indent_1).concat(t.reporterDescriptionLabel(), ": ").concat(violation.message)); if (violation.code) { consola_1.default.log("".concat(indent_1).concat(t.reporterCodeLabel(), ": ").concat(violation.code)); } if (violation.suggestions && violation.suggestions.length > 0) { var suggestionSeparator = language === 'zh' ? '; ' : ' | '; var suggestionLine = violation.suggestions .map(function (suggestion) { return t.reporterFormatSuggestion(suggestion); }) .join(suggestionSeparator); consola_1.default.log("".concat(indent_1).concat(t.reporterSuggestionLabel(), ": ").concat(suggestionLine)); } }); } records.length = 0; resetCounters(); return summary; }; var resetCounters = function () { totalViolations = 0; errorViolations = 0; severityCounts.error = 0; severityCounts.warning = 0; severityCounts.optimizing = 0; }; return Object.assign({ error: error, errorAtLine: errorAtLine, errorAtSpan: errorAtSpan }, { forRule: buildRuleReporter, flush: flush, }); } function getLoggerForSeverity(severity) { var _a; return (_a = severityLoggers[severity]) !== null && _a !== void 0 ? _a : consola_1.default.error; } function resolveLine(record, offsets) { if (typeof record.line === 'number') { return record.line; } if (record.span) { return offsetToLine(record.span.start, offsets); } return undefined; } function extractSpan(spanLike) { if (!spanLike) { return undefined; } if (hasSpan(spanLike)) { return spanLike.span; } return spanLike; } function hasSpan(value) { return typeof value === 'object' && value !== null && 'span' in value; } function buildLineOffsets(source) { var offsets = [0]; for (var index = 0; index < source.length; index += 1) { if (source[index] === '\n') { offsets.push(index + 1); } } return offsets; } function offsetToLine(offset, offsets) { var low = 0; var high = offsets.length - 1; while (low <= high) { var mid = Math.floor((low + high) / 2); var current = offsets[mid]; if (current === offset) { return mid + 1; } if (current < offset) { low = mid + 1; } else { high = mid - 1; } } return high + 1; }