13af6ab5fSopenharmony_ci/* 23af6ab5fSopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License. 53af6ab5fSopenharmony_ci * You may obtain a copy of the License at 63af6ab5fSopenharmony_ci * 73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83af6ab5fSopenharmony_ci * 93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and 133af6ab5fSopenharmony_ci * limitations under the License. 143af6ab5fSopenharmony_ci */ 153af6ab5fSopenharmony_ci 163af6ab5fSopenharmony_ciimport * as fs from 'node:fs'; 173af6ab5fSopenharmony_ciimport * as os from 'node:os'; 183af6ab5fSopenharmony_ciimport * as path from 'node:path'; 193af6ab5fSopenharmony_ciimport * as readline from 'node:readline'; 203af6ab5fSopenharmony_ciimport type { CommandLineOptions } from '../lib/CommandLineOptions'; 213af6ab5fSopenharmony_ciimport { lint } from '../lib/LinterRunner'; 223af6ab5fSopenharmony_ciimport { Logger } from '../lib/Logger'; 233af6ab5fSopenharmony_ciimport type { ProblemInfo } from '../lib/ProblemInfo'; 243af6ab5fSopenharmony_ciimport { TypeScriptLinter } from '../lib/TypeScriptLinter'; 253af6ab5fSopenharmony_ciimport { parseCommandLine } from './CommandLineParser'; 263af6ab5fSopenharmony_ciimport { compileLintOptions } from './Compiler'; 273af6ab5fSopenharmony_ciimport type { LintOptions } from '../lib/LintOptions'; 283af6ab5fSopenharmony_ci 293af6ab5fSopenharmony_ciexport function run(): void { 303af6ab5fSopenharmony_ci const commandLineArgs = process.argv.slice(2); 313af6ab5fSopenharmony_ci if (commandLineArgs.length === 0) { 323af6ab5fSopenharmony_ci Logger.info('Command line error: no arguments'); 333af6ab5fSopenharmony_ci process.exit(-1); 343af6ab5fSopenharmony_ci } 353af6ab5fSopenharmony_ci 363af6ab5fSopenharmony_ci const cmdOptions = parseCommandLine(commandLineArgs); 373af6ab5fSopenharmony_ci 383af6ab5fSopenharmony_ci if (cmdOptions.testMode) { 393af6ab5fSopenharmony_ci TypeScriptLinter.testMode = true; 403af6ab5fSopenharmony_ci } 413af6ab5fSopenharmony_ci 423af6ab5fSopenharmony_ci TypeScriptLinter.initGlobals(); 433af6ab5fSopenharmony_ci 443af6ab5fSopenharmony_ci if (!cmdOptions.ideMode) { 453af6ab5fSopenharmony_ci const compileOptions = compileLintOptions(cmdOptions); 463af6ab5fSopenharmony_ci const result = lint(compileOptions, getEtsLoaderPath(compileOptions)); 473af6ab5fSopenharmony_ci process.exit(result.errorNodes > 0 ? 1 : 0); 483af6ab5fSopenharmony_ci } else { 493af6ab5fSopenharmony_ci runIDEMode(cmdOptions); 503af6ab5fSopenharmony_ci } 513af6ab5fSopenharmony_ci} 523af6ab5fSopenharmony_ci 533af6ab5fSopenharmony_cifunction getTempFileName(): string { 543af6ab5fSopenharmony_ci return path.join(os.tmpdir(), Math.floor(Math.random() * 10000000).toString() + '_linter_tmp_file.ts'); 553af6ab5fSopenharmony_ci} 563af6ab5fSopenharmony_ci 573af6ab5fSopenharmony_cifunction showJSONMessage(problems: ProblemInfo[][]): void { 583af6ab5fSopenharmony_ci const jsonMessage = problems[0].map((x) => { 593af6ab5fSopenharmony_ci return { 603af6ab5fSopenharmony_ci line: x.line, 613af6ab5fSopenharmony_ci column: x.column, 623af6ab5fSopenharmony_ci start: x.start, 633af6ab5fSopenharmony_ci end: x.end, 643af6ab5fSopenharmony_ci type: x.type, 653af6ab5fSopenharmony_ci suggest: x.suggest, 663af6ab5fSopenharmony_ci rule: x.rule, 673af6ab5fSopenharmony_ci severity: x.severity, 683af6ab5fSopenharmony_ci autofix: x.autofix 693af6ab5fSopenharmony_ci }; 703af6ab5fSopenharmony_ci }); 713af6ab5fSopenharmony_ci Logger.info(`{"linter messages":${JSON.stringify(jsonMessage)}}`); 723af6ab5fSopenharmony_ci} 733af6ab5fSopenharmony_ci 743af6ab5fSopenharmony_cifunction runIDEMode(cmdOptions: CommandLineOptions): void { 753af6ab5fSopenharmony_ci TypeScriptLinter.ideMode = true; 763af6ab5fSopenharmony_ci const tmpFileName = getTempFileName(); 773af6ab5fSopenharmony_ci // read data from stdin 783af6ab5fSopenharmony_ci const writeStream = fs.createWriteStream(tmpFileName, { flags: 'w' }); 793af6ab5fSopenharmony_ci const rl = readline.createInterface({ 803af6ab5fSopenharmony_ci input: process.stdin, 813af6ab5fSopenharmony_ci output: writeStream, 823af6ab5fSopenharmony_ci terminal: false 833af6ab5fSopenharmony_ci }); 843af6ab5fSopenharmony_ci 853af6ab5fSopenharmony_ci rl.on('line', (line: string) => { 863af6ab5fSopenharmony_ci fs.appendFileSync(tmpFileName, line + '\n'); 873af6ab5fSopenharmony_ci }); 883af6ab5fSopenharmony_ci rl.once('close', () => { 893af6ab5fSopenharmony_ci // end of input 903af6ab5fSopenharmony_ci writeStream.close(); 913af6ab5fSopenharmony_ci cmdOptions.inputFiles = [tmpFileName]; 923af6ab5fSopenharmony_ci if (cmdOptions.parsedConfigFile) { 933af6ab5fSopenharmony_ci cmdOptions.parsedConfigFile.fileNames.push(tmpFileName); 943af6ab5fSopenharmony_ci } 953af6ab5fSopenharmony_ci const compileOptions = compileLintOptions(cmdOptions); 963af6ab5fSopenharmony_ci const result = lint(compileOptions, getEtsLoaderPath(compileOptions)); 973af6ab5fSopenharmony_ci const problems = Array.from(result.problemsInfos.values()); 983af6ab5fSopenharmony_ci if (problems.length === 1) { 993af6ab5fSopenharmony_ci showJSONMessage(problems); 1003af6ab5fSopenharmony_ci } else { 1013af6ab5fSopenharmony_ci Logger.error('Unexpected error: could not lint file'); 1023af6ab5fSopenharmony_ci } 1033af6ab5fSopenharmony_ci fs.unlinkSync(tmpFileName); 1043af6ab5fSopenharmony_ci }); 1053af6ab5fSopenharmony_ci} 1063af6ab5fSopenharmony_ci 1073af6ab5fSopenharmony_ciexport function getEtsLoaderPath(compileOptions: LintOptions): string | undefined { 1083af6ab5fSopenharmony_ci const tsProgram = compileOptions.tscCompiledProgram.getProgram(); 1093af6ab5fSopenharmony_ci return tsProgram.getCompilerOptions().etsLoaderPath; 1103af6ab5fSopenharmony_ci} 111