UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

200 lines (198 loc) 9.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ErrorUpdater = void 0; const tslib_1 = require("tslib"); const child_process_1 = require("child_process"); const fs_extra_1 = tslib_1.__importDefault(require("fs-extra")); const common_1 = require("../common"); const updater_lookup_1 = require("./error-updaters/updater-lookup"); const logger_1 = require("../angular15/utils/logger"); class ErrorUpdater { /** * Executes 'ng lint' and attempts to fix returned errors. * @param {boolean} audit Flag indicating if upgrade is running it audit mode * @param {string[]} updateSource Array used to emit logs to file * @returns {Promise<number>} Count of unresolved errors. */ async resolveLintErrors(audit, updateSource) { const errors = await this.parseLintErrors(audit); const unresolvedCount = await this.fixErrors(audit, errors, updateSource); return new Promise((resolve) => resolve(unresolvedCount)); } /** * Executes 'ng build' and attempts to fix returned errors. * @param {boolean} audit Flag indicating if upgrade is running it audit mode * @param {string[]} updateSource Array used to emit logs to file * @returns {Promise<number>} Count of unresolved errors. */ async resolveBuildErrors(audit, updateSource) { // If running in audit mode, we don't want to build if (audit) { return new Promise(resolve => resolve(0)); } const errors = await this.parseBuildErrors(); const unresolvedCount = await this.fixErrors(false, errors, updateSource); logger_1.Logger.log('INFO - unresolvedCount' + unresolvedCount); return new Promise((resolve) => resolve(unresolvedCount)); } parseLintErrors(audit) { // If audit is true, run without --fix flag const cmd = audit ? 'ng lint --project module-app --format json' : 'ng lint --project module-app --fix --format json'; console.log('Linting, please wait...'); return new Promise((resolve) => { (0, child_process_1.exec)(cmd, (_, stdout) => { const output = JSON.parse(stdout); const results = []; for (const error of output) { if (error.ruleSeverity === 'error') { results.push({ filePath: error.name, type: error.ruleName, message: error.failure, position: { line: error.startPosition.line, character: error.startPosition.character }, resolved: common_1.ResolveState.Unresolved }); } } resolve(results); }); }); } parseBuildErrors() { console.log('Building, please wait...'); return new Promise((resolve) => (0, child_process_1.exec)('ng build', (_error, _stdout, stderr) => { resolve(this.parseBuildErrorsCore(stderr)); })); } async fixErrors(audit, errors, updateSource, angularVersion) { if (!errors || !errors.length) { return new Promise(resolve => resolve(0)); } let unresolvedCount = errors.length; for (const error of errors) { let message = `File path: ${error.filePath}`; console.log(message); updateSource.push(message + '\n'); let fileData = common_1.Common.readFileData(error.filePath); if (!fileData) { message = `Couldn't retrieve file data for path ${error.filePath}. Please verify this path is valid.`; console.log(message); updateSource.push(message + '\n'); continue; } fileData = await this.fixError(audit, fileData, error, updateSource, angularVersion); if (error.resolved === common_1.ResolveState.Resolved) { unresolvedCount--; } if (fileData) { fs_extra_1.default.writeFileSync(error.filePath, fileData); } console.log(''); updateSource.push('\n'); } return new Promise(resolve => resolve(unresolvedCount)); } async fixError(audit, fileData, error, updateSource, augularVerion) { let message = `\tType: ${error.type}`; console.log(message); updateSource.push(message + '\n'); message = `\tLine: ${error?.position?.line}`; console.log(message); updateSource.push(message + '\n'); message = `\tChar: ${error?.position?.character}`; console.log(message); updateSource.push(message + '\n'); message = `\tMessage: ${error.message}`; console.log(message); updateSource.push(message + '\n'); if (audit) { return fileData; } const updaterLookup = updater_lookup_1.UpdaterLookup.initialize(augularVerion); const updater = updaterLookup[error.type]; logger_1.Logger.log(`error.type = ${error.type}`); logger_1.Logger.log(updater ? `Found updater for ${error.type}` : `No updater found for ${error.type}`); const result = updater != null ? await updater.update(fileData, error) : fileData; message = `\tResolved: ${error.resolved}\n`; console.log(message); updateSource.push(message + '\n'); return new Promise(resolve => resolve(result)); } parseBuildErrorsCore(log) { const captureAll = /[\s\S]+?(?=(Error|Warning):)/g; // Capture array of build error/warning output by file const captureFilePath = /(?<=Error: )(.+)(?=:\d+:\d+)/g; // Capture file path of individual error const captureErrorPosition = /(?<=Error: .+)(\d+:\d+)(?= - error)/g; // Capture file position of individual error const captureErrorCode = /(?<=Error:.+- error )(TS\d+)/g; // Capture error code of individual error const captureErrorMessage = /(?<=TS\d+: ).+/g; // Capture error message of individual error log = log + '\n\n\nWarning:'; const buildOutputByCode = log.match(captureAll); const results = []; if (!buildOutputByCode) { return results; } for (const file of buildOutputByCode) { const filePath = file.match(captureFilePath); // If no file path found, this match doesn't contain errors if (!filePath || filePath.length === 0) { continue; } const errorPositionString = file.match(captureErrorPosition); // If there isn't a position found this isn't a parsable error, skip to next file if (!errorPositionString || errorPositionString.length === 0) { continue; } const splitValues = errorPositionString[0].split(':'); const errorPosition = { line: parseInt(splitValues[0], null), character: parseInt(splitValues[1], null) }; const errorCode = file.match(captureErrorCode); // Couldn't get error code, skip to next file if (!errorCode || errorCode.length === 0) { continue; } const errorMessage = file.match(captureErrorMessage); results.push({ filePath: filePath[0], type: errorCode[0], message: errorMessage[0], position: errorPosition, resolved: common_1.ResolveState.Unresolved }); } return results; } parseBuildWarningsCore(log) { // Capture array of build error/warning output by file const captureAll = /[\s\S]+?(?=(Error|Warning):)/g; // Capture file path of individual error const captureFilePath = /([^\s\r\n].*\.css)\s*(?=:)/g; log = log + '\n\n\nWarning:'; const buildOutputByCode = log.match(captureAll); const results = []; if (!buildOutputByCode) { return results; } for (const file of buildOutputByCode) { const filePath = file.match(captureFilePath); // If no file path found, this match doesn't contain errors if (!filePath || filePath.length === 0) { continue; } let errorCode; if (file.includes('css-syntax-error')) { errorCode = ['css-syntax-error']; } // Couldn't get error code, skip to next file if (!errorCode || errorCode.length === 0) { continue; } results.push({ filePath: filePath[0], type: errorCode[0], message: file, resolved: common_1.ResolveState.Unresolved }); } return results; } } exports.ErrorUpdater = ErrorUpdater; //# sourceMappingURL=error-updater.js.map