UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

295 lines (293 loc) 15.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EslintUpgrader = exports.EslintUpgraderMessages = exports.UpgradeType = void 0; const tslib_1 = require("tslib"); const fs_extra_1 = tslib_1.__importStar(require("fs-extra")); const common_1 = require("../common"); const child_process_1 = require("child_process"); /** * Represents the type of upgrade that needs to be performed. */ var UpgradeType; (function (UpgradeType) { UpgradeType["WithBaseConfig"] = "WithBaseConfig"; UpgradeType["WithoutBaseConfig"] = "WithoutBaseConfig"; UpgradeType["NoOperation"] = "NoOperation"; })(UpgradeType = exports.UpgradeType || (exports.UpgradeType = {})); /** * Represents the messages that are displayed during the upgrade process. */ var EslintUpgraderMessages; (function (EslintUpgraderMessages) { EslintUpgraderMessages["StartingUpgrade"] = "Starting upgrade eslinting process..."; EslintUpgraderMessages["CheckingFilePaths"] = "Checking file paths..."; EslintUpgraderMessages["UpdateTypeWithBaseConfig"] = "UpdateType: WithBaseConfig"; EslintUpgraderMessages["UpdateTypeWithoutBaseConfig"] = "UpdateType: WithoutBaseConfig"; EslintUpgraderMessages["UpdateTypeWithoutBoth"] = "UpdateType: NoOperation"; EslintUpgraderMessages["ExitWithoutBaseConfig"] = "Exiting upgrade eslinting process..."; EslintUpgraderMessages["RCANoTsConfigFile"] = "Please manually create a tsconfig.json file in the root of your project."; EslintUpgraderMessages["GettingTsConfigFile"] = "Getting tsconfig.json file..."; EslintUpgraderMessages["UpdateTsConfigContent"] = "Updating tsconfig.json content..."; EslintUpgraderMessages["RevertTsConfigContent"] = "Reverting tsconfig.json content..."; EslintUpgraderMessages["RenameTsBaseConfig"] = "Renaming tsconfig.base.json to tsconfig.base.json_backup..."; EslintUpgraderMessages["RevertTsBaseConfig"] = "Renaming tsconfig.base.json_backup to tsconfig.base.json..."; EslintUpgraderMessages["UpdateEslintConfig"] = "Updating .eslintrc.json content..."; EslintUpgraderMessages["UpdatePolyfills"] = "Updating polyfills.ts content..."; EslintUpgraderMessages["UpdateKarmaFile"] = "Updating karma.conf.js content..."; EslintUpgraderMessages["FinalizeInfoLintFix"] = "There are eslint violations that needs fix... After fixing the violations, please run the following commands:\n\n npx eslint . --fix \n\n gulp lintApp \n\n gulp build \n\n "; EslintUpgraderMessages["Completed"] = "Upgrade completed!"; })(EslintUpgraderMessages = exports.EslintUpgraderMessages || (exports.EslintUpgraderMessages = {})); /** * This is the main class of the EslintUpgrader tool. * It is responsible for upgrading the Tslint to Eslint. */ class EslintUpgrader { tsconfigBaseFilePath; tsconfigFilePath; angularFilePath; debug = false; libUpgrade = false; tsconfigBaseFileName = 'tsconfig.base.json'; tsconfigFileName = 'tsconfig.json'; tsconfigBaseFileNameBackUp = 'tsconfig.base.json_backup'; angularFileName = 'angular.json'; eslintConfigFileName = '.eslintrc.json'; eslintConfigFileContent = { "extends": "./node_modules/@microsoft/windows-admin-center-sdk/tools/code-formatter/.eslintrc.base.json" }; polifillsFilePath = './src/polyfills.ts'; karmaConfigFilePath = './src/karma.conf.js'; eslintDisable = 'eslint-disable'; targetGulpLintFilePath = '.\\gulpfile.ts\\common\\lint.ts'; targetGulpLintIndexFilePath = './gulpfile.ts/index.ts'; targetGulpLintUiTestAutomationFilePath = '.\\gulpfile.ts\\common\\ui-test-automation.ts'; /** * The main upgrade process * @param debug - Indicates if the debug mode is enabled. * @returns Promise<void> - Returns a promise that resolves when the upgrade process is completed. */ async upgrade(debug = false) { this.debug = !!debug; this.logger(EslintUpgraderMessages.StartingUpgrade); this.logger(EslintUpgraderMessages.CheckingFilePaths); const upgradeType = this.checkFileExists(); this.checkLibUpgrade(); switch (upgradeType) { case UpgradeType.WithBaseConfig: this.logger(EslintUpgraderMessages.UpdateTypeWithBaseConfig); this.updateTsConfigContent(); this.renameTsBaseConfig(); await this.addEslintSchematics(); await this.esLintSchematicsRunModuleApp(); if (this.libUpgrade) { await this.esLintSchematicsRunModuleLib(); } await this.uninstallDependencies(); await this.installDependencies(); await this.replaceEslintConfig(); this.updateTsConfigContent(true); this.renameTsBaseConfig(true); await this.replaceGulpLintFile(); this.cleanUpPolyfills(); this.cleanUpKarmaConfigFile(); await this.fixEslintErrors(); await this.gulpBuild(); break; case UpgradeType.WithoutBaseConfig: this.logger(EslintUpgraderMessages.UpdateTypeWithoutBaseConfig); await this.addEslintSchematics(); await this.esLintSchematicsRunModuleApp(); if (this.libUpgrade) { await this.esLintSchematicsRunModuleLib(); } await this.uninstallDependencies(); await this.installDependencies(); await this.replaceEslintConfig(); await this.replaceGulpLintFile(); this.cleanUpPolyfills(); this.cleanUpKarmaConfigFile(); await this.fixEslintErrors(); await this.gulpBuild(); break; case UpgradeType.NoOperation: this.logger(EslintUpgraderMessages.UpdateTypeWithoutBoth); this.logger(EslintUpgraderMessages.ExitWithoutBaseConfig); this.logger(EslintUpgraderMessages.RCANoTsConfigFile); break; default: break; } this.logger(EslintUpgraderMessages.Completed); } constructor() { common_1.Common.rootPath = process.cwd(); this.updateBasicPaths(); } updateBasicPaths() { this.tsconfigBaseFilePath = common_1.Common.rootPath + '\\' + this.tsconfigBaseFileName; this.tsconfigFilePath = common_1.Common.rootPath + '\\' + this.tsconfigFileName; this.angularFilePath = common_1.Common.rootPath + '\\' + this.angularFileName; } checkLibUpgrade() { const angularFilePathExists = (0, fs_extra_1.pathExists)(this.angularFilePath); if (!angularFilePathExists) { return; } const angularFileContent = common_1.Common.readFileData(this.angularFilePath); this.libUpgrade = !!angularFileContent.includes('module-lib'); } checkFileExists() { const tsconfigBaseFilePathExists = (0, fs_extra_1.pathExists)(this.tsconfigBaseFilePath); const tsconfigFilePathExists = (0, fs_extra_1.pathExists)(this.tsconfigFilePath); if (tsconfigBaseFilePathExists && tsconfigFilePathExists) { return UpgradeType.WithBaseConfig; } else if (tsconfigFilePathExists) { return UpgradeType.WithoutBaseConfig; } else { return UpgradeType.NoOperation; } } updateTsConfigContent(revert = false) { revert ? this.logger(EslintUpgraderMessages.RevertTsConfigContent) : this.logger(EslintUpgraderMessages.UpdateTsConfigContent); revert ? this.updateFile(this.tsconfigFilePath, `// "extends": "./${this.tsconfigBaseFileName}"`, `"extends": "./${this.tsconfigBaseFileName}"`) : this.updateFile(this.tsconfigFilePath, `"extends": "./${this.tsconfigBaseFileName}"`, `// "extends": "./${this.tsconfigBaseFileName}"`); } updateFile(filePath, prev, target) { this.logger('Updating file...' + filePath + ',' + prev + ',' + target + '...'); let fileData = common_1.Common.readFileData(filePath); fileData = fileData.replace(prev, target); fs_extra_1.default.writeFileSync(filePath, fileData); } renameTsBaseConfig(revert = false) { revert ? this.logger(EslintUpgraderMessages.RenameTsBaseConfig) : this.logger(EslintUpgraderMessages.RevertTsBaseConfig); const cmd = revert ? `git mv ./${this.tsconfigBaseFileNameBackUp} ./${this.tsconfigBaseFileName}` : `git mv ./${this.tsconfigBaseFileName} ./${this.tsconfigBaseFileNameBackUp}`; this.runCommand(cmd); } async addEslintSchematics() { const cmd = 'ng add @angular-eslint/schematics --skip-confirmation'; this.logger(cmd); await this.runCommand(cmd); } async esLintSchematicsRunModuleApp() { const cmd = 'ng g @angular-eslint/schematics:convert-tslint-to-eslint module-app'; this.logger(cmd); await this.runCommand(cmd); } async esLintSchematicsRunModuleLib() { const cmd = 'ng g @angular-eslint/schematics:convert-tslint-to-eslint module-lib'; this.logger(cmd); await this.runCommand(cmd); } /** * It updates to the eslintrc.json file on the root of the project. */ async replaceEslintConfig() { const formattedNewContent = JSON.stringify(this.eslintConfigFileContent, null, 2) .replace('}', '}\n'); this.logger(EslintUpgraderMessages.UpdateEslintConfig); if (fs_extra_1.default.existsSync(`./${this.eslintConfigFileName}`)) { this.logger('Updating eslint file'); common_1.Common.writeFileData(`./${this.eslintConfigFileName}`, formattedNewContent); } else { this.logger('Creating new eslint file'); common_1.Common.writeFile(`./${this.eslintConfigFileName}`, formattedNewContent); } // race condition for the eslintrc file not being released by the writeFile function. await this.sleep(1000); } async uninstallDependencies() { const cmd = 'npm uninstall codelyzer gulp-tslint rxjs-tslint rxjs-tslint-rules tslint tslint-consistent-codestyle tslint-eslint-rules tslint-microsoft-contrib'; this.logger(cmd); await this.runCommand(cmd); const removeForRollBackCmd = 'npm uninstall gulp-eslint eslint eslint-plugin-angular eslint-plugin-import eslint-plugin-jsdoc eslint-plugin-jsonc eslint-plugin-prefer-arrow ' + '@typescript-eslint/eslint-plugin @typescript-eslint/parser @angular-eslint/builder @angular-eslint/eslint-plugin @angular-eslint/eslint-plugin-template @angular-eslint/schematics ' + '@angular-eslint/template-parser'; this.logger(removeForRollBackCmd); await this.runCommand(removeForRollBackCmd); } async installDependencies() { const cmd = 'npm install gulp-eslint@6.0.0 eslint@7.6.0 eslint-plugin-angular@4.1.0 eslint-plugin-import@2.21.0 eslint-plugin-jsdoc@36.1.1 eslint-plugin-jsonc@2.8.0 eslint-plugin-prefer-arrow@1.2.3 ' + '@typescript-eslint/eslint-plugin@4.16.1 @typescript-eslint/parser@4.16.1 @angular-eslint/builder@4.3.1 @angular-eslint/eslint-plugin@4.3.1 @angular-eslint/eslint-plugin-template@4.3.1 ' + '@angular-eslint/schematics@4.3.1 @angular-eslint/template-parser@4.3.1 --save-dev'; this.logger(cmd); await this.runCommand(cmd); } async fixEslintErrors() { const rootFileLinterFix = 'npx eslint . --fix'; this.logger(rootFileLinterFix); await this.runCommand(rootFileLinterFix, true, EslintUpgraderMessages.FinalizeInfoLintFix); const projectLinterFix = 'npx ng lint --fix'; this.logger(projectLinterFix); await this.runCommand(projectLinterFix, true, EslintUpgraderMessages.FinalizeInfoLintFix); } async replaceGulpLintFile() { const cmd = `del ${this.targetGulpLintFilePath}`; this.logger(cmd); await this.runCommand(cmd); if ((0, fs_extra_1.pathExists)(this.targetGulpLintIndexFilePath)) { this.updateFile(this.targetGulpLintIndexFilePath, `import { LintModule } from './common/lint'`, `import { LintModule } from '../node_modules/@microsoft/windows-admin-center-sdk/tools/code-formatter/lint'`); } if ((0, fs_extra_1.pathExists)(this.targetGulpLintUiTestAutomationFilePath)) { this.updateFile(this.targetGulpLintUiTestAutomationFilePath, `import { LintModule } from './lint'`, `import { LintModule } from '../../node_modules/@microsoft/windows-admin-center-sdk/tools/code-formatter/lint'`); // The new UI automation framework will remove this line. // This is for the repositories that has not yet onboraded to the new frawework. this.updateFile(this.targetGulpLintUiTestAutomationFilePath, `export const uiTestAutomation = series(LintModule.lintUiTestAutomation, buildUiTestAutomation);`, `export const uiTestAutomation = series(LintModule.lintUiTestAutomation_legacy, buildUiTestAutomation);`); } } async gulpBuild() { const cmd = 'gulp build'; this.logger(cmd); await this.runCommand(cmd); } cleanUpPolyfills() { this.logger(EslintUpgraderMessages.UpdatePolyfills); const fileDataInLines = common_1.Common.readFileData(this.polifillsFilePath).split('\n'); const newLines = fileDataInLines.filter(line => !line.includes(this.eslintDisable)); common_1.Common.writeFileData(this.polifillsFilePath, newLines.join('\n')); } cleanUpKarmaConfigFile() { this.logger(EslintUpgraderMessages.UpdateKarmaFile); this.updateFile(this.karmaConfigFilePath, `module.exports = (config) => {`, `module.exports = function (config) {`); } runCommand(cmd, forceDebug = false, finalizeInfo = undefined) { console.log(`Running ${cmd}`); return new Promise((resolve) => { const child = (0, child_process_1.exec)(cmd, (error, stdout, stderr) => { if (error) { console.error(` exec error: ${error}`); return; } stdout.split('\n').filter(line => line.trimEnd()).forEach(line => console.log(line)); stderr.split('\n').filter(line => line.trimEnd()).forEach(line => console.error(line)); resolve(); }); if (this.debug || forceDebug) { child.stdout.on('data', (data) => { data.split('\n').filter(line => line.trimEnd()).forEach(line => console.log(` ${line}`)); }); } child.stderr.on('data', (data) => { data.split('\n').filter(line => line.trimEnd()).forEach(line => console.error(` ${line}`)); }); child.on('close', (code) => { console.log(`exitCode: ${code}`); if (code !== 0 && finalizeInfo) { this.logger(finalizeInfo); this.logger(EslintUpgraderMessages.Completed); } }); }); } logger(value, prefix = 'Main thread') { console.log(`${prefix} - ${value}`); } sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } } exports.EslintUpgrader = EslintUpgrader; //# sourceMappingURL=main.js.map