UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

1 lines 18.1 kB
{"version":3,"sources":["../../../packages/tools/wac-cli/src/eslint/main.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,oBAAY,WAAW;IACnB,cAAc,mBAAmB;IACjC,iBAAiB,sBAAsB;IACvC,WAAW,gBAAgB;CAC9B;AAED;;GAEG;AACH,oBAAY,sBAAsB;IAC9B,eAAe,0CAA0C;IACzD,iBAAiB,2BAA2B;IAC5C,wBAAwB,+BAA+B;IACvD,2BAA2B,kCAAkC;IAC7D,qBAAqB,4BAA4B;IACjD,qBAAqB,yCAAyC;IAC9D,iBAAiB,6EAA6E;IAC9F,mBAAmB,kCAAkC;IACrD,qBAAqB,sCAAsC;IAC3D,qBAAqB,uCAAuC;IAC5D,kBAAkB,gEAAgE;IAClF,kBAAkB,gEAAgE;IAClF,kBAAkB,uCAAuC;IACzD,eAAe,qCAAqC;IACpD,eAAe,sCAAsC;IACrD,mBAAmB,yMAIlB;IACD,SAAS,uBAAuB;CACnC;AAED;;;GAGG;AACH,qBAAa,cAAc;IACvB,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,eAAe,CAAS;IAEhC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAwB;IAC7D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAA+B;IAC1E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAElD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAoB;IACzD,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAEtC;IACF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAwB;IAC1D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAyB;IAC7D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmB;IACjD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAqC;IAC5E,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAA4B;IACxE,OAAO,CAAC,QAAQ,CAAC,sCAAsC,CAAmD;IAE1G;;;;OAIG;IACU,OAAO,CAAC,KAAK,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;;IAwElD,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,kBAAkB;YAOZ,mBAAmB;YAOnB,4BAA4B;YAO5B,4BAA4B;IAO1C;;OAEG;IACU,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;YAkBnC,qBAAqB;YAcrB,mBAAmB;YASnB,eAAe;YAUf,mBAAmB;YA4BnB,SAAS;IAMvB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,UAAU;IAmClB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,KAAK;CAGhB","file":"main.d.ts","sourcesContent":["import fse, { pathExists } from 'fs-extra';\r\nimport { Common } from '../common';\r\nimport { exec } from 'child_process';\r\n\r\n/**\r\n * Represents the type of upgrade that needs to be performed.\r\n */\r\nexport enum UpgradeType {\r\n WithBaseConfig = 'WithBaseConfig',\r\n WithoutBaseConfig = 'WithoutBaseConfig',\r\n NoOperation = 'NoOperation'\r\n}\r\n\r\n/**\r\n * Represents the messages that are displayed during the upgrade process.\r\n */\r\nexport enum EslintUpgraderMessages {\r\n StartingUpgrade = 'Starting upgrade eslinting process...',\r\n CheckingFilePaths = 'Checking file paths...',\r\n UpdateTypeWithBaseConfig = 'UpdateType: WithBaseConfig',\r\n UpdateTypeWithoutBaseConfig = 'UpdateType: WithoutBaseConfig',\r\n UpdateTypeWithoutBoth = 'UpdateType: NoOperation',\r\n ExitWithoutBaseConfig = 'Exiting upgrade eslinting process...',\r\n RCANoTsConfigFile = 'Please manually create a tsconfig.json file in the root of your project.',\r\n GettingTsConfigFile = 'Getting tsconfig.json file...',\r\n UpdateTsConfigContent = 'Updating tsconfig.json content...',\r\n RevertTsConfigContent = 'Reverting tsconfig.json content...',\r\n RenameTsBaseConfig = 'Renaming tsconfig.base.json to tsconfig.base.json_backup...',\r\n RevertTsBaseConfig = 'Renaming tsconfig.base.json_backup to tsconfig.base.json...',\r\n UpdateEslintConfig = 'Updating .eslintrc.json content...',\r\n UpdatePolyfills = 'Updating polyfills.ts content...',\r\n UpdateKarmaFile = 'Updating karma.conf.js content...',\r\n FinalizeInfoLintFix = `There are eslint violations that needs fix... After fixing the violations, please run the following commands:\\n\r\n npx eslint . --fix \\n\r\n gulp lintApp \\n\r\n gulp build \\n\r\n `,\r\n Completed = 'Upgrade completed!'\r\n}\r\n\r\n/**\r\n * This is the main class of the EslintUpgrader tool.\r\n * It is responsible for upgrading the Tslint to Eslint.\r\n */\r\nexport class EslintUpgrader {\r\n private tsconfigBaseFilePath: string;\r\n private tsconfigFilePath: string;\r\n private angularFilePath: string;\r\n\r\n private debug = false;\r\n private libUpgrade = false;\r\n\r\n private readonly tsconfigBaseFileName = 'tsconfig.base.json';\r\n private readonly tsconfigFileName = 'tsconfig.json';\r\n private readonly tsconfigBaseFileNameBackUp = 'tsconfig.base.json_backup';\r\n private readonly angularFileName = 'angular.json';\r\n\r\n private readonly eslintConfigFileName = '.eslintrc.json';\r\n private readonly eslintConfigFileContent = {\r\n \"extends\": \"./node_modules/@microsoft/windows-admin-center-sdk/tools/code-formatter/.eslintrc.base.json\"\r\n };\r\n private readonly polifillsFilePath = './src/polyfills.ts';\r\n private readonly karmaConfigFilePath = './src/karma.conf.js';\r\n private readonly eslintDisable = 'eslint-disable'\r\n private readonly targetGulpLintFilePath = '.\\\\gulpfile.ts\\\\common\\\\lint.ts';\r\n private readonly targetGulpLintIndexFilePath = './gulpfile.ts/index.ts';\r\n private readonly targetGulpLintUiTestAutomationFilePath = '.\\\\gulpfile.ts\\\\common\\\\ui-test-automation.ts';\r\n\r\n /**\r\n * The main upgrade process\r\n * @param debug - Indicates if the debug mode is enabled.\r\n * @returns Promise<void> - Returns a promise that resolves when the upgrade process is completed.\r\n */\r\n public async upgrade(debug = false): Promise<void> {\r\n this.debug = !!debug;\r\n\r\n this.logger(EslintUpgraderMessages.StartingUpgrade);\r\n this.logger(EslintUpgraderMessages.CheckingFilePaths);\r\n\r\n const upgradeType = this.checkFileExists();\r\n this.checkLibUpgrade();\r\n\r\n switch (upgradeType) {\r\n case UpgradeType.WithBaseConfig:\r\n this.logger(EslintUpgraderMessages.UpdateTypeWithBaseConfig);\r\n\r\n this.updateTsConfigContent();\r\n this.renameTsBaseConfig();\r\n await this.addEslintSchematics();\r\n await this.esLintSchematicsRunModuleApp();\r\n\r\n if (this.libUpgrade) {\r\n await this.esLintSchematicsRunModuleLib();\r\n }\r\n\r\n await this.uninstallDependencies();\r\n await this.installDependencies();\r\n await this.replaceEslintConfig();\r\n this.updateTsConfigContent(true);\r\n this.renameTsBaseConfig(true);\r\n await this.replaceGulpLintFile();\r\n this.cleanUpPolyfills();\r\n this.cleanUpKarmaConfigFile();\r\n await this.fixEslintErrors();\r\n await this.gulpBuild();\r\n\r\n break;\r\n case UpgradeType.WithoutBaseConfig:\r\n this.logger(EslintUpgraderMessages.UpdateTypeWithoutBaseConfig);\r\n\r\n await this.addEslintSchematics();\r\n await this.esLintSchematicsRunModuleApp();\r\n\r\n if (this.libUpgrade) {\r\n await this.esLintSchematicsRunModuleLib();\r\n }\r\n\r\n await this.uninstallDependencies();\r\n await this.installDependencies();\r\n await this.replaceEslintConfig();\r\n await this.replaceGulpLintFile();\r\n this.cleanUpPolyfills();\r\n this.cleanUpKarmaConfigFile();\r\n await this.fixEslintErrors();\r\n await this.gulpBuild();\r\n\r\n break;\r\n case UpgradeType.NoOperation:\r\n this.logger(EslintUpgraderMessages.UpdateTypeWithoutBoth);\r\n this.logger(EslintUpgraderMessages.ExitWithoutBaseConfig);\r\n this.logger(EslintUpgraderMessages.RCANoTsConfigFile);\r\n\r\n break;\r\n default:\r\n break;\r\n }\r\n\r\n this.logger(EslintUpgraderMessages.Completed);\r\n }\r\n\r\n constructor() {\r\n Common.rootPath = process.cwd();\r\n this.updateBasicPaths();\r\n }\r\n\r\n private updateBasicPaths(): void {\r\n this.tsconfigBaseFilePath = Common.rootPath + '\\\\' + this.tsconfigBaseFileName;\r\n this.tsconfigFilePath = Common.rootPath + '\\\\' + this.tsconfigFileName;\r\n this.angularFilePath = Common.rootPath + '\\\\' + this.angularFileName;\r\n }\r\n\r\n private checkLibUpgrade(): void {\r\n const angularFilePathExists = pathExists(this.angularFilePath);\r\n if (!angularFilePathExists) {\r\n return;\r\n }\r\n\r\n const angularFileContent = Common.readFileData(this.angularFilePath);\r\n this.libUpgrade = !!angularFileContent.includes('module-lib');\r\n }\r\n\r\n private checkFileExists(): UpgradeType {\r\n const tsconfigBaseFilePathExists = pathExists(this.tsconfigBaseFilePath);\r\n const tsconfigFilePathExists = pathExists(this.tsconfigFilePath);\r\n if (tsconfigBaseFilePathExists && tsconfigFilePathExists) {\r\n return UpgradeType.WithBaseConfig;\r\n } else if (tsconfigFilePathExists) {\r\n return UpgradeType.WithoutBaseConfig;\r\n } else {\r\n return UpgradeType.NoOperation;\r\n }\r\n }\r\n\r\n private updateTsConfigContent(revert = false) {\r\n revert ? this.logger(EslintUpgraderMessages.RevertTsConfigContent) : this.logger(EslintUpgraderMessages.UpdateTsConfigContent);\r\n\r\n revert ?\r\n this.updateFile(this.tsconfigFilePath, `// \"extends\": \"./${this.tsconfigBaseFileName}\"`, `\"extends\": \"./${this.tsconfigBaseFileName}\"`) :\r\n this.updateFile(this.tsconfigFilePath, `\"extends\": \"./${this.tsconfigBaseFileName}\"`, `// \"extends\": \"./${this.tsconfigBaseFileName}\"`);\r\n }\r\n\r\n private updateFile(filePath: string, prev: string, target: string): void {\r\n this.logger('Updating file...' + filePath + ',' + prev + ',' + target + '...');\r\n\r\n let fileData = Common.readFileData(filePath);\r\n fileData = fileData.replace(prev, target);\r\n fse.writeFileSync(filePath, fileData);\r\n }\r\n\r\n private renameTsBaseConfig(revert = false): void {\r\n revert ? this.logger(EslintUpgraderMessages.RenameTsBaseConfig) : this.logger(EslintUpgraderMessages.RevertTsBaseConfig);\r\n\r\n const cmd = revert ? `git mv ./${this.tsconfigBaseFileNameBackUp} ./${this.tsconfigBaseFileName}` : `git mv ./${this.tsconfigBaseFileName} ./${this.tsconfigBaseFileNameBackUp}`;\r\n this.runCommand(cmd);\r\n }\r\n\r\n private async addEslintSchematics(): Promise<void> {\r\n const cmd = 'ng add @angular-eslint/schematics --skip-confirmation';\r\n\r\n this.logger(cmd);\r\n await this.runCommand(cmd);\r\n }\r\n\r\n private async esLintSchematicsRunModuleApp(): Promise<void> {\r\n const cmd = 'ng g @angular-eslint/schematics:convert-tslint-to-eslint module-app';\r\n\r\n this.logger(cmd);\r\n await this.runCommand(cmd);\r\n }\r\n\r\n private async esLintSchematicsRunModuleLib(): Promise<void> {\r\n const cmd = 'ng g @angular-eslint/schematics:convert-tslint-to-eslint module-lib';\r\n\r\n this.logger(cmd);\r\n await this.runCommand(cmd);\r\n }\r\n\r\n /**\r\n * It updates to the eslintrc.json file on the root of the project.\r\n */\r\n public async replaceEslintConfig(): Promise<void> {\r\n const formattedNewContent = JSON.stringify(this.eslintConfigFileContent, null, 2)\r\n .replace('}', '}\\n')\r\n\r\n this.logger(EslintUpgraderMessages.UpdateEslintConfig);\r\n\r\n if (fse.existsSync(`./${this.eslintConfigFileName}`)) {\r\n this.logger('Updating eslint file');\r\n Common.writeFileData(`./${this.eslintConfigFileName}`, formattedNewContent);\r\n } else {\r\n this.logger('Creating new eslint file');\r\n Common.writeFile(`./${this.eslintConfigFileName}`, formattedNewContent);\r\n }\r\n\r\n // race condition for the eslintrc file not being released by the writeFile function.\r\n await this.sleep(1000);\r\n }\r\n\r\n private async uninstallDependencies(): Promise<void> {\r\n const cmd = 'npm uninstall codelyzer gulp-tslint rxjs-tslint rxjs-tslint-rules tslint tslint-consistent-codestyle tslint-eslint-rules tslint-microsoft-contrib';\r\n\r\n this.logger(cmd);\r\n await this.runCommand(cmd);\r\n\r\n const removeForRollBackCmd = 'npm uninstall gulp-eslint eslint eslint-plugin-angular eslint-plugin-import eslint-plugin-jsdoc eslint-plugin-jsonc eslint-plugin-prefer-arrow ' +\r\n '@typescript-eslint/eslint-plugin @typescript-eslint/parser @angular-eslint/builder @angular-eslint/eslint-plugin @angular-eslint/eslint-plugin-template @angular-eslint/schematics ' +\r\n '@angular-eslint/template-parser'\r\n\r\n this.logger(removeForRollBackCmd);\r\n await this.runCommand(removeForRollBackCmd);\r\n }\r\n\r\n private async installDependencies(): Promise<void> {\r\n 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 ' +\r\n '@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 ' +\r\n '@angular-eslint/schematics@4.3.1 @angular-eslint/template-parser@4.3.1 --save-dev';\r\n\r\n this.logger(cmd);\r\n await this.runCommand(cmd);\r\n }\r\n\r\n private async fixEslintErrors(): Promise<void> {\r\n const rootFileLinterFix = 'npx eslint . --fix';\r\n this.logger(rootFileLinterFix);\r\n await this.runCommand(rootFileLinterFix, true, EslintUpgraderMessages.FinalizeInfoLintFix);\r\n\r\n const projectLinterFix = 'npx ng lint --fix';\r\n this.logger(projectLinterFix);\r\n await this.runCommand(projectLinterFix, true, EslintUpgraderMessages.FinalizeInfoLintFix);\r\n }\r\n\r\n private async replaceGulpLintFile(): Promise<void> {\r\n const cmd = `del ${this.targetGulpLintFilePath}`;\r\n\r\n this.logger(cmd);\r\n await this.runCommand(cmd);\r\n\r\n if (pathExists(this.targetGulpLintIndexFilePath)) {\r\n this.updateFile(\r\n this.targetGulpLintIndexFilePath,\r\n `import { LintModule } from './common/lint'`,\r\n `import { LintModule } from '../node_modules/@microsoft/windows-admin-center-sdk/tools/code-formatter/lint'`);\r\n }\r\n\r\n if (pathExists(this.targetGulpLintUiTestAutomationFilePath)) {\r\n this.updateFile(\r\n this.targetGulpLintUiTestAutomationFilePath,\r\n `import { LintModule } from './lint'`,\r\n `import { LintModule } from '../../node_modules/@microsoft/windows-admin-center-sdk/tools/code-formatter/lint'`);\r\n\r\n // The new UI automation framework will remove this line.\r\n // This is for the repositories that has not yet onboraded to the new frawework.\r\n this.updateFile(\r\n this.targetGulpLintUiTestAutomationFilePath,\r\n `export const uiTestAutomation = series(LintModule.lintUiTestAutomation, buildUiTestAutomation);`,\r\n `export const uiTestAutomation = series(LintModule.lintUiTestAutomation_legacy, buildUiTestAutomation);`);\r\n }\r\n }\r\n\r\n private async gulpBuild(): Promise<void> {\r\n const cmd = 'gulp build';\r\n this.logger(cmd);\r\n await this.runCommand(cmd);\r\n }\r\n\r\n private cleanUpPolyfills(): void {\r\n this.logger(EslintUpgraderMessages.UpdatePolyfills);\r\n\r\n const fileDataInLines = Common.readFileData(this.polifillsFilePath).split('\\n');\r\n const newLines = fileDataInLines.filter(line => !line.includes(this.eslintDisable));\r\n Common.writeFileData(this.polifillsFilePath, newLines.join('\\n'));\r\n }\r\n\r\n private cleanUpKarmaConfigFile(): void {\r\n this.logger(EslintUpgraderMessages.UpdateKarmaFile);\r\n\r\n this.updateFile(\r\n this.karmaConfigFilePath,\r\n `module.exports = (config) => {`,\r\n `module.exports = function (config) {`);\r\n }\r\n\r\n private runCommand(cmd: string, forceDebug = false, finalizeInfo = undefined): Promise<void> {\r\n console.log(`Running ${cmd}`);\r\n return new Promise((resolve) => {\r\n const child = exec(cmd, (error, stdout, stderr) => {\r\n if (error) {\r\n console.error(` exec error: ${error}`);\r\n return;\r\n }\r\n\r\n stdout.split('\\n').filter(line => line.trimEnd()).forEach(line => console.log(line));\r\n stderr.split('\\n').filter(line => line.trimEnd()).forEach(line => console.error(line));\r\n\r\n resolve();\r\n });\r\n\r\n if (this.debug || forceDebug) {\r\n child.stdout.on('data', (data) => {\r\n data.split('\\n').filter(line => line.trimEnd()).forEach(line => console.log(` ${line}`));\r\n });\r\n }\r\n\r\n child.stderr.on('data', (data) => {\r\n data.split('\\n').filter(line => line.trimEnd()).forEach(line => console.error(` ${line}`));\r\n });\r\n\r\n child.on('close', (code) => {\r\n console.log(`exitCode: ${code}`);\r\n if (code !== 0 && finalizeInfo) {\r\n this.logger(finalizeInfo);\r\n this.logger(EslintUpgraderMessages.Completed);\r\n }\r\n });\r\n });\r\n }\r\n\r\n private logger(value: EslintUpgraderMessages | string, prefix = 'Main thread') {\r\n console.log(`${prefix} - ${value}`);\r\n }\r\n\r\n private sleep(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n}\r\n"]}