Skip to content

Standardized outputs: CLI summaries, log details #408

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cli/runCli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

Expand Down
2 changes: 1 addition & 1 deletion src/conversion/convertConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/errors/conversionError.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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!`,
);
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/errors/conversionError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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),
);
}
Expand Down
116 changes: 81 additions & 35 deletions src/reporting/reportConversionResults.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe("reportConversionResults", () => {
const conversionResults = createEmptyConversionResults({
converted: new Map<string, ESLintRuleOptions>([
[
"tslint-rule-one",
`tslint-rule-one`,
{
ruleArguments: ["a", "b"],
ruleName: "tslint-rule-one",
Expand All @@ -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(
Expand All @@ -49,7 +53,7 @@ describe("reportConversionResults", () => {
const conversionResults = createEmptyConversionResults({
converted: new Map<string, ESLintRuleOptions>([
[
"tslint-rule-one",
`tslint-rule-one`,
{
notices: ["1", "2"],
ruleArguments: ["a", "b"],
Expand All @@ -63,28 +67,37 @@ 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 () => {
// Arrange
const conversionResults = createEmptyConversionResults({
converted: new Map<string, ESLintRuleOptions>([
[
"tslint-rule-one",
`tslint-rule-one`,
{
notices: ["1", "2"],
ruleArguments: ["a", "b"],
Expand All @@ -93,7 +106,7 @@ describe("reportConversionResults", () => {
},
],
[
"tslint-rule-two",
`tslint-rule-two`,
{
notices: ["3", "4"],
ruleArguments: ["c", "d"],
Expand All @@ -107,23 +120,32 @@ 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 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`,
);
});

Expand All @@ -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.`,
);
});
Expand All @@ -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.`,
);
});
Expand All @@ -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".',
);
});

Expand All @@ -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".',
);
});

Expand All @@ -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`,
);
});
});
49 changes: 24 additions & 25 deletions src/reporting/reportConversionResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type ReportConversionResultsDependencies = {

export const reportConversionResults = async (
dependencies: ReportConversionResultsDependencies,
outputPath: string,
ruleConversionResults: RuleConversionResults,
) => {
const packageManager = await dependencies.choosePackageManager();
Expand All @@ -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.`,
],
);
}
Expand All @@ -61,29 +61,28 @@ const logNotices = (converted: Map<string, ESLintRuleOptions>, 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);
};
16 changes: 9 additions & 7 deletions src/reporting/reportEditorSettingConversionResults.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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".',
);
});

Expand All @@ -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".',
);
});
});
Loading