diff --git a/src/cli/runCli.ts b/src/cli/runCli.ts index 2d6a85e88..a1a353861 100644 --- a/src/cli/runCli.ts +++ b/src/cli/runCli.ts @@ -45,7 +45,7 @@ export const runCli = async ( } } - dependencies.logger.stdout.write(chalk.greenBright("✅ All is well! ✅\n")); + dependencies.logger.stdout.write(chalk.greenBright(`${EOL}✅ All is well! ✅\n`)); return ResultStatus.Succeeded; }; diff --git a/src/conversion/convertConfig.ts b/src/conversion/convertConfig.ts index 2305bade1..67e8b93d1 100644 --- a/src/conversion/convertConfig.ts +++ b/src/conversion/convertConfig.ts @@ -57,7 +57,7 @@ export const convertConfig = async ( } // 5. A summary of the results is printed to the user's console - await dependencies.reportConversionResults(simplifiedConfiguration); + await dependencies.reportConversionResults(settings.config, simplifiedConfiguration); return { status: ResultStatus.Succeeded, diff --git a/src/errors/conversionError.test.ts b/src/errors/conversionError.test.ts index 4a41dd70e..c9981f296 100644 --- a/src/errors/conversionError.test.ts +++ b/src/errors/conversionError.test.ts @@ -33,7 +33,7 @@ describe(ConversionError, () => { // Assert expect(summary).toEqual( - `Error: multiple output eslint-rule ESLint rule options were generated, but tslint-to-eslint-config doesn't have "merger" logic to deal with this.${EOL}Please file an issue at https://github.com/typescript-eslint/tslint-to-eslint-config/issues/new?template=missing_merger.md 🙏`, + `Error: multiple output eslint-rule ESLint rule options were generated, but tslint-to-eslint-config doesn't have "merger" logic to deal with this.${EOL}Please file an issue at https://github.com/typescript-eslint/tslint-to-eslint-config/issues/new?template=missing_merger.md. Thanks!`, ); }); }); diff --git a/src/errors/conversionError.ts b/src/errors/conversionError.ts index c2766c8f7..1482a5e17 100644 --- a/src/errors/conversionError.ts +++ b/src/errors/conversionError.ts @@ -11,7 +11,7 @@ export class ConversionError implements ErrorSummary { return new ConversionError( [ `Error: multiple output ${eslintRule} ESLint rule options were generated, but tslint-to-eslint-config doesn't have "merger" logic to deal with this.`, - `Please file an issue at https://github.com/typescript-eslint/tslint-to-eslint-config/issues/new?template=missing_merger.md 🙏`, + `Please file an issue at https://github.com/typescript-eslint/tslint-to-eslint-config/issues/new?template=missing_merger.md. Thanks!`, ].join(EOL), ); } diff --git a/src/reporting/reportConversionResults.test.ts b/src/reporting/reportConversionResults.test.ts index bc9807923..466d8dc0d 100644 --- a/src/reporting/reportConversionResults.test.ts +++ b/src/reporting/reportConversionResults.test.ts @@ -19,7 +19,7 @@ describe("reportConversionResults", () => { const conversionResults = createEmptyConversionResults({ converted: new Map([ [ - "tslint-rule-one", + `tslint-rule-one`, { ruleArguments: ["a", "b"], ruleName: "tslint-rule-one", @@ -32,7 +32,11 @@ describe("reportConversionResults", () => { const { choosePackageManager, logger } = createStubDependencies(); // Act - await reportConversionResults({ choosePackageManager, logger }, conversionResults); + await reportConversionResults( + { choosePackageManager, logger }, + ".eslintrc.js", + conversionResults, + ); // Assert expectEqualWrites( @@ -49,7 +53,7 @@ describe("reportConversionResults", () => { const conversionResults = createEmptyConversionResults({ converted: new Map([ [ - "tslint-rule-one", + `tslint-rule-one`, { notices: ["1", "2"], ruleArguments: ["a", "b"], @@ -63,20 +67,29 @@ describe("reportConversionResults", () => { const { choosePackageManager, logger } = createStubDependencies(); // Act - await reportConversionResults({ choosePackageManager, logger }, conversionResults); + await reportConversionResults( + { choosePackageManager, logger }, + ".eslintrc.js", + conversionResults, + ); // Assert expectEqualWrites( logger.stdout.write, `✨ 1 rule replaced with its ESLint equivalent. ✨${EOL}`, `❗ 1 ESLint rule behaves differently from its TSLint counterpart ❗`, - ` * tslint-rule-one:`, - ` - 1`, - ` - 2`, + ` Check ${logger.debugFileName} for details.`, ``, `⚡ 3 packages are required for running with ESLint. ⚡`, ` yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint --dev`, ); + expectEqualWrites( + logger.info.write, + `1 ESLint rule behaves differently from its TSLint counterpart:`, + ` * tslint-rule-one:`, + ` - 1`, + ` - 2`, + ); }); it("logs successful conversions when there are multiple converted rules", async () => { @@ -84,7 +97,7 @@ describe("reportConversionResults", () => { const conversionResults = createEmptyConversionResults({ converted: new Map([ [ - "tslint-rule-one", + `tslint-rule-one`, { notices: ["1", "2"], ruleArguments: ["a", "b"], @@ -93,7 +106,7 @@ describe("reportConversionResults", () => { }, ], [ - "tslint-rule-two", + `tslint-rule-two`, { notices: ["3", "4"], ruleArguments: ["c", "d"], @@ -107,7 +120,11 @@ describe("reportConversionResults", () => { const { choosePackageManager, logger } = createStubDependencies(); // Act - await reportConversionResults({ choosePackageManager, logger }, conversionResults); + await reportConversionResults( + { choosePackageManager, logger }, + ".eslintrc.js", + conversionResults, + ); // Assert expectEqualWrites( @@ -115,15 +132,20 @@ describe("reportConversionResults", () => { `✨ 2 rules replaced with their ESLint equivalents. ✨`, ``, `❗ 2 ESLint rules behave differently from their TSLint counterparts ❗`, + ` Check ${logger.debugFileName} for details.`, + ``, + `⚡ 3 packages are required for running with ESLint. ⚡`, + ` yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint --dev`, + ); + expectEqualWrites( + logger.info.write, + `2 ESLint rules behave differently from their TSLint counterparts:`, ` * tslint-rule-one:`, ` - 1`, ` - 2`, ` * tslint-rule-two:`, ` - 3`, ` - 4`, - ``, - `⚡ 3 packages are required for running with ESLint. ⚡`, - ` yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint --dev`, ); }); @@ -136,12 +158,16 @@ describe("reportConversionResults", () => { const { choosePackageManager, logger } = createStubDependencies(); // Act - await reportConversionResults({ choosePackageManager, logger }, conversionResults); + await reportConversionResults( + { choosePackageManager, logger }, + ".eslintrc.js", + conversionResults, + ); // Assert expectEqualWrites( logger.stderr.write, - "❌ 1 error thrown. ❌", + `❌ 1 error thrown. ❌`, ` Check ${logger.debugFileName} for details.`, ); }); @@ -155,12 +181,16 @@ describe("reportConversionResults", () => { const { choosePackageManager, logger } = createStubDependencies(); // Act - await reportConversionResults({ choosePackageManager, logger }, conversionResults); + await reportConversionResults( + { choosePackageManager, logger }, + ".eslintrc.js", + conversionResults, + ); // Assert expectEqualWrites( logger.stderr.write, - "❌ 2 errors thrown. ❌", + `❌ 2 errors thrown. ❌`, ` Check ${logger.debugFileName} for details.`, ); }); @@ -180,20 +210,26 @@ describe("reportConversionResults", () => { const { choosePackageManager, logger } = createStubDependencies(); // Act - await reportConversionResults({ choosePackageManager, logger }, conversionResults); + await reportConversionResults( + { choosePackageManager, logger }, + ".eslintrc.js", + conversionResults, + ); // Assert expectEqualWrites( logger.stdout.write, - "❓ 1 rule does not yet have an ESLint equivalent ❓", - ` See generated log file; defaulting to eslint-plugin-tslint for it.`, - "", - "⚡ 3 packages are required for running with ESLint. ⚡", - " yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint --dev", + `❓ 1 rule is not known by tslint-to-eslint-config to have an ESLint equivalent. ❓`, + ` The "@typescript-eslint/tslint/config" section of .eslintrc.js configures eslint-plugin-tslint to run it in TSLint within ESLint.`, + ` Check ${logger.debugFileName} for details.`, + ``, + `⚡ 3 packages are required for running with ESLint. ⚡`, + ` yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint --dev`, ); expectEqualWrites( logger.info.write, - 'tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-rule-one"', + `1 rule is not known by tslint-to-eslint-config to have an ESLint equivalent:`, + ' * tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-rule-one".', ); }); @@ -217,21 +253,27 @@ describe("reportConversionResults", () => { const { choosePackageManager, logger } = createStubDependencies(); // Act - await reportConversionResults({ choosePackageManager, logger }, conversionResults); + await reportConversionResults( + { choosePackageManager, logger }, + ".eslintrc.js", + conversionResults, + ); // Assert expectEqualWrites( logger.stdout.write, - "❓ 2 rules do not yet have ESLint equivalents ❓", - ` See generated log file; defaulting to eslint-plugin-tslint for these rules.`, - "", - "⚡ 3 packages are required for running with ESLint. ⚡", - " yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint --dev", + `❓ 2 rules are not known by tslint-to-eslint-config to have ESLint equivalents. ❓`, + ` The "@typescript-eslint/tslint/config" section of .eslintrc.js configures eslint-plugin-tslint to run them in TSLint within ESLint.`, + ` Check ${logger.debugFileName} for details.`, + ``, + `⚡ 3 packages are required for running with ESLint. ⚡`, + ` yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint --dev`, ); expectEqualWrites( logger.info.write, - 'tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-rule-one"', - 'tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-rule-two"', + `2 rules are not known by tslint-to-eslint-config to have ESLint equivalents:`, + ' * tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-rule-one".', + ' * tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-rule-two".', ); }); @@ -244,13 +286,17 @@ describe("reportConversionResults", () => { const { choosePackageManager, logger } = createStubDependencies(); // Act - await reportConversionResults({ choosePackageManager, logger }, conversionResults); + await reportConversionResults( + { choosePackageManager, logger }, + ".eslintrc.js", + conversionResults, + ); // Assert expectEqualWrites( logger.stdout.write, - "⚡ 5 packages are required for running with ESLint. ⚡", - " yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint plugin-one plugin-two --dev", + `⚡ 5 packages are required for running with ESLint. ⚡`, + ` yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint plugin-one plugin-two --dev`, ); }); }); diff --git a/src/reporting/reportConversionResults.ts b/src/reporting/reportConversionResults.ts index b68b25963..f3cc475b8 100644 --- a/src/reporting/reportConversionResults.ts +++ b/src/reporting/reportConversionResults.ts @@ -20,6 +20,7 @@ export type ReportConversionResultsDependencies = { export const reportConversionResults = async ( dependencies: ReportConversionResultsDependencies, + outputPath: string, ruleConversionResults: RuleConversionResults, ) => { const packageManager = await dependencies.choosePackageManager(); @@ -36,14 +37,13 @@ export const reportConversionResults = async ( if (ruleConversionResults.missing.length !== 0) { logMissingConversionTarget( "rule", - (setting: TSLintRuleOptions) => - `tslint-to-eslint-config does not know the ESLint equivalent for TSLint's "${setting.ruleName}"${EOL}`, + (setting: TSLintRuleOptions) => setting.ruleName, ruleConversionResults.missing, dependencies.logger, [ - ruleConversionResults.missing.length === 1 - ? "defaulting to eslint-plugin-tslint for it." - : "defaulting to eslint-plugin-tslint for these rules.", + `The "@typescript-eslint/tslint/config" section of ${outputPath} configures eslint-plugin-tslint to run ${ + ruleConversionResults.missing.length === 1 ? "it" : "them" + } in TSLint within ESLint.`, ], ); } @@ -61,29 +61,28 @@ const logNotices = (converted: Map, logger: Logger) = (ruleOptions) => ruleOptions.notices && ruleOptions.notices.length >= 1, ) as RuleWithNotices[]; - if (rulesWithNotices.length !== 0) { - logger.stdout.write(chalk.yellowBright(`${EOL}❗ ${rulesWithNotices.length} ESLint`)); + if (rulesWithNotices.length === 0) { + return; + } - if (rulesWithNotices.length === 1) { - logger.stdout.write( - chalk.yellowBright( - ` rule behaves differently from its TSLint counterpart ❗${EOL}`, - ), - ); - } else { - logger.stdout.write( - chalk.yellowBright( - ` rules behave differently from their TSLint counterparts ❗${EOL}`, - ), - ); - } + const behavior = + rulesWithNotices.length === 1 + ? " behaves differently from its TSLint counterpart" + : "s behave differently from their TSLint counterparts"; - for (const rule of rulesWithNotices) { - logger.stdout.write(chalk.yellow(` * ${rule.ruleName}:${EOL}`)); + logger.stdout.write( + chalk.blueBright(`${EOL}❗ ${rulesWithNotices.length} ESLint rule${behavior} ❗${EOL}`), + ); + logger.stdout.write(chalk.blue(` Check ${logger.debugFileName} for details.${EOL}`)); + logger.info.write(`${rulesWithNotices.length} ESLint rule${behavior}:${EOL}`); - for (const notice of rule.notices) { - logger.stdout.write(chalk.yellow(` - ${notice}${EOL}`)); - } + for (const rule of rulesWithNotices) { + logger.info.write(` * ${rule.ruleName}:${EOL}`); + + for (const notice of rule.notices) { + logger.info.write(` - ${notice}${EOL}`); } } + + logger.info.write(EOL); }; diff --git a/src/reporting/reportEditorSettingConversionResults.test.ts b/src/reporting/reportEditorSettingConversionResults.test.ts index 9bbff1386..a4ced16e8 100644 --- a/src/reporting/reportEditorSettingConversionResults.test.ts +++ b/src/reporting/reportEditorSettingConversionResults.test.ts @@ -121,12 +121,13 @@ describe("reportEditorSettingConversionResults", () => { // Assert expectEqualWrites( logger.stdout.write, - `❓ 1 editor setting does not yet have an ESLint equivalent ❓`, - ` See generated log file.`, + `❓ 1 editor setting is not known by tslint-to-eslint-config to have an ESLint equivalent. ❓`, + ` Check ${logger.debugFileName} for details.`, ); expectEqualWrites( logger.info.write, - 'tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-editor-setting-one"', + `1 editor setting is not known by tslint-to-eslint-config to have an ESLint equivalent:`, + ' * tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-editor-setting-one".', ); }); @@ -151,13 +152,14 @@ describe("reportEditorSettingConversionResults", () => { // Assert expectEqualWrites( logger.stdout.write, - `❓ 2 editor settings do not yet have ESLint equivalents ❓`, - ` See generated log file.`, + `❓ 2 editor settings are not known by tslint-to-eslint-config to have ESLint equivalents. ❓`, + ` Check ${logger.debugFileName} for details.`, ); expectEqualWrites( logger.info.write, - 'tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-editor-setting-one"', - 'tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-editor-setting-two"', + `2 editor settings are not known by tslint-to-eslint-config to have ESLint equivalents:`, + ' * tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-editor-setting-one".', + ' * tslint-to-eslint-config does not know the ESLint equivalent for TSLint\'s "tslint-editor-setting-two".', ); }); }); diff --git a/src/reporting/reportEditorSettingConversionResults.ts b/src/reporting/reportEditorSettingConversionResults.ts index 85e06ac5b..38271d6ef 100644 --- a/src/reporting/reportEditorSettingConversionResults.ts +++ b/src/reporting/reportEditorSettingConversionResults.ts @@ -1,8 +1,5 @@ -import { EOL } from "os"; - import { Logger } from "../adapters/logger"; import { EditorSettingConversionResults } from "../editorSettings/convertEditorSettings"; -import { EditorSetting } from "../editorSettings/types"; import { logFailedConversions, logMissingConversionTarget, @@ -30,13 +27,9 @@ export const reportEditorSettingConversionResults = ( } if (editorSettingConversionResults.missing.length !== 0) { - const missingEditorSettingOutputMapping = ( - editorSetting: Pick, - ) => - `tslint-to-eslint-config does not know the ESLint equivalent for TSLint's "${editorSetting.editorSettingName}"${EOL}`; logMissingConversionTarget( "editor setting", - missingEditorSettingOutputMapping, + (editorSetting) => editorSetting.editorSettingName, editorSettingConversionResults.missing, dependencies.logger, ); diff --git a/src/reporting/reportOutputs.ts b/src/reporting/reportOutputs.ts index 93e8c0488..79a9a613e 100644 --- a/src/reporting/reportOutputs.ts +++ b/src/reporting/reportOutputs.ts @@ -29,7 +29,7 @@ export const logFailedConversions = (failed: ErrorSummary[], logger: Logger) => logger.stderr.write(chalk.red(" thrown.")); logger.stderr.write(chalk.redBright(` ❌${EOL}`)); logger.info.write(failed.map((failed) => failed.getSummary()).join("\n\n") + "\n\n"); - logger.stderr.write(chalk.gray(` Check ${logger.debugFileName} for details.${EOL}`)); + logger.stderr.write(chalk.red(` Check ${logger.debugFileName} for details.${EOL}`)); }; export const logMissingConversionTarget = ( @@ -39,31 +39,33 @@ export const logMissingConversionTarget = ( logger: Logger, additionalWarnings: string[] = [], ) => { + const headline = + missing.length === 1 + ? ` ${conversionTypeName} is not known by tslint-to-eslint-config to have an ESLint equivalent` + : ` ${conversionTypeName}s are not known by tslint-to-eslint-config to have ESLint equivalents`; + logger.stdout.write(chalk.yellowBright(`️${EOL}❓ ${missing.length}`)); - logger.stdout.write( - chalk.yellow( - missing.length === 1 - ? ` ${conversionTypeName} does not yet have an ESLint equivalent` - : ` ${conversionTypeName}s do not yet have ESLint equivalents`, - ), - ); + logger.stdout.write(chalk.yellow(`${headline}.`)); logger.stdout.write(chalk.yellowBright(` ❓${EOL}`)); - logger.stdout.write(chalk.yellow(` See generated log file`)); - if (additionalWarnings.length > 0) { - logger.stdout.write(chalk.yellow("; ")); - - for (const warning of additionalWarnings) { - logger.stdout.write(chalk.yellow(warning)); - } - } else { - logger.stdout.write(chalk.yellow(".")); + for (const warning of additionalWarnings) { + logger.stdout.write(chalk.yellow(` ${warning}${EOL}`)); } + logger.stdout.write(chalk.yellow(` Check ${logger.debugFileName} for details.${EOL}`)); + + logger.info.write(`${missing.length}${headline}:${EOL}`); logger.info.write( - chalk.yellow(missing.map((conversion) => missingOutputMapping(conversion)).join("")), + missing + .map( + (conversion) => + ` * tslint-to-eslint-config does not know the ESLint equivalent for TSLint's "${missingOutputMapping( + conversion, + )}".${EOL}`, + ) + .join(""), ); - logger.stdout.write(chalk.yellow(EOL)); + logger.info.write(EOL); }; export const logMissingPackages = ( @@ -83,5 +85,5 @@ export const logMissingPackages = ( logger.stdout.write(chalk.cyanBright(" ⚡")); logger.stdout.write(`${EOL} `); logger.stdout.write(chalk.cyan(installationMessages[packageManager](packageNames.join(" ")))); - logger.stdout.write(EOL.repeat(2)); + logger.stdout.write(EOL); };