UNPKG

@angular-eslint/schematics

Version:
120 lines (119 loc) 6.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertTSLintDisableCommentsForProject = exports.createConvertToESLintConfig = void 0; const core_1 = require("@angular-devkit/core"); const child_process_1 = require("child_process"); const tmp_1 = require("tmp"); const utils_1 = require("../utils"); const tslintToEslintConfigVersion = // eslint-disable-next-line @typescript-eslint/no-var-requires require('../../package.json').devDependencies['tslint-to-eslint-config']; let tslintToEslintConfigLibrary; function getTslintToEslintConfigLibrary(context) { if (tslintToEslintConfigLibrary) { return tslintToEslintConfigLibrary; } try { // This is usually not available at runtime but makes it easier to work with in our tests return require('tslint-to-eslint-config'); // eslint-disable-next-line no-empty } catch (e) { } context.logger.info('\nINFO: We are now installing the "tslint-to-eslint-config" package into a tmp directory to aid with the conversion'); context.logger.info('\nThis may take a minute or two...\n'); /** * In order to avoid all users of angular-eslint needing to have tslint-to-eslint-config (and therefore tslint) * in their node_modules, we dynamically install and uninstall the library as part of the conversion * process. */ const tempDir = (0, tmp_1.dirSync)().name; (0, child_process_1.execSync)(`npm i -D tslint-to-eslint-config@${tslintToEslintConfigVersion}`, { cwd: tempDir, stdio: 'ignore', }); tslintToEslintConfigLibrary = require(require.resolve('tslint-to-eslint-config', { paths: [tempDir], })); return tslintToEslintConfigLibrary; } function createConvertToESLintConfig(context) { return async function convertToESLintConfig(pathToTslintJson, tslintJson) { const { findReportedConfiguration, createESLintConfiguration, joinConfigConversionResults, } = getTslintToEslintConfigLibrary(context); const reportedConfiguration = await findReportedConfiguration('npx tslint --print-config', pathToTslintJson); if (reportedConfiguration instanceof Error) { if (reportedConfiguration.message.includes('unknown option `--print-config')) { throw new Error('\nError: TSLint v5.18 required in order to run this schematic. Please update your version and try again.\n'); } /** * Make a print-config issue easier to understand for the end user. * This error could occur if, for example, the user does not have a TSLint plugin installed correctly that they * reference in their config. */ const printConfigFailureMessageStart = 'Command failed: npx tslint --print-config "tslint.json"'; if (reportedConfiguration.message.startsWith(printConfigFailureMessageStart)) { throw new Error(`\nThere was a critical error when trying to inspect your tslint.json: \n${reportedConfiguration.message.replace(printConfigFailureMessageStart, '')}`); } throw new Error(`Unexpected error: ${reportedConfiguration.message}`); } const originalConfigurations = { tslint: { full: reportedConfiguration, raw: tslintJson, }, }; const summarizedConfiguration = await createESLintConfiguration(originalConfigurations); const expectedESLintPlugins = [ // These are added to support the ng-cli-compat configs 'eslint-plugin-jsdoc', 'eslint-plugin-prefer-arrow', 'eslint-plugin-import', // These are already covered by our recommended config, and are installed by the `ng add` schematic '@angular-eslint/eslint-plugin', '@angular-eslint/eslint-plugin-template', ]; const convertedESLintConfig = joinConfigConversionResults(summarizedConfiguration, originalConfigurations); return { convertedESLintConfig, unconvertedTSLintRules: summarizedConfiguration.missing, ensureESLintPlugins: Array.from(summarizedConfiguration.plugins).filter((pluginName) => !expectedESLintPlugins.includes(pluginName)), }; }; } exports.createConvertToESLintConfig = createConvertToESLintConfig; function likelyContainsTSLintComment(fileContent) { return fileContent.includes('tslint:'); } function convertTSLintDisableCommentsForProject(projectName) { return (tree, context) => { /** * We need to avoid a direct dependency on tslint-to-eslint-config * and ensure we are only resolving the dependency from the user's * node_modules on demand (it will be installed as part of the * conversion schematic). */ const { convertFileComments } = getTslintToEslintConfigLibrary(context); const workspaceJson = (0, utils_1.readJsonInTree)(tree, 'angular.json'); const existingProjectConfig = workspaceJson.projects[projectName]; let pathRoot = ''; // Default Angular CLI project at the root of the workspace if (existingProjectConfig.root === '') { pathRoot = 'src'; } else { pathRoot = existingProjectConfig.root; } return (0, utils_1.visitNotIgnoredFiles)((filePath, host) => { if (!filePath.endsWith('.ts')) { return; } const fileContent = host.read(filePath).toString('utf-8'); // Avoid updating files if we don't have to if (!likelyContainsTSLintComment(fileContent)) { return; } const updatedFileContent = convertFileComments({ fileContent, filePath }); host.overwrite(filePath, updatedFileContent); }, (0, core_1.normalize)(pathRoot)); }; } exports.convertTSLintDisableCommentsForProject = convertTSLintDisableCommentsForProject;