Skip to content

Commit

Permalink
feat: add pretty-printed logs. Closes #3
Browse files Browse the repository at this point in the history
  • Loading branch information
radiovisual committed Sep 24, 2024
1 parent e6ffe16 commit e975198
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 102 deletions.
9 changes: 6 additions & 3 deletions keeli.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
"rules": {
"no-untranslated-messages": "error",
"no-empty-messages": "error",
"no-extra-whitespace": "error",
"no-html-messages": "error",
"no-extra-whitespace": {
"severity": "error",
"ignoreKeys": []
},
"no-html-messages": "kjh",
"no-missing-keys": "error",
"no-invalid-variables": "error",
"no-invalid-variables": "warn",
"no-malformed-keys": {
"severity": "error",
"namingConvention": "kebab-case"
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"dependencies": {
"@formatjs/icu-messageformat-parser": "^2.7.8",
"chalk": "^4.0.0",
"cli-table3": "^0.6.5",
"flattie": "^1.1.1",
"lodash": "^4.17.21"
},
Expand Down
176 changes: 142 additions & 34 deletions src/classes/logger.class.ts
Original file line number Diff line number Diff line change
@@ -1,67 +1,175 @@
import { ProblemStore } from "./problem-store.class.ts";
import { Problem } from "./problem.class.ts";
import Table, {
HorizontalTableRow,
VerticalTableRow,
CrossTableRow,
Cell,
} from "cli-table3";
import chalk from "chalk";
import { SEVERITY_LEVEL } from "../constants.ts";

class Logger {
private problemStore: ProblemStore;
private validationProblems: Problem[];
private validationProblems: { [locale: string]: Problem[] };
private configurationProblems: Problem[];
private ignoredConfigurationProblems: Problem[];
private ignoredValidationProblems: Problem[];
private isDryRun: boolean;

public constructor(problemStore: ProblemStore) {
public constructor(problemStore: ProblemStore, isDryRun: boolean) {
this.problemStore = problemStore;
this.validationProblems = problemStore.getValidationProblems();
this.configurationProblems = problemStore.getConfigurationProblems();
this.ignoredConfigurationProblems =
problemStore.getIgnoredConfigurationProblems();
this.ignoredValidationProblems =
problemStore.getIgnoredValidationProblems();
this.isDryRun = isDryRun;
}

// TODO: Clean up this summary when the pretty reporter is done https://github.com/radiovisual/keeli/issues/3
public logErrors() {
this.problemStore.getAllProblems().forEach((problem) => {
console.log(
`${problem.severity} | ${problem?.locale ?? ""} ${problem.message}`
);
Object.entries(this.validationProblems).forEach(
([locale, problemArray]) => {
const problemTable = this.getNewTable();
console.log(`\n\nProblems found in locale: ${chalk.cyan(locale)}`);
problemArray.forEach((problem) => {
problemTable.push(this.getTableRow(problem));
});
console.log(problemTable.toString());
}
);

const configTable = this.getNewTable();
this.configurationProblems.forEach((problem) => {
configTable.push(this.getTableRow(problem));
});
console.log("---");

if (this.configurationProblems.length > 0) {
console.log(`\n\nProblems found in ${chalk.cyan("configuration")}`);
console.log(configTable.toString());
}

console.log(this.getPrintSummary());

if (this.isDryRun) {
console.log(
chalk.cyan(`\n\ndryRun is enabled for keeli. Errors will not throw.`)
);
}
}

// TODO: Clean up this summary when the pretty reporter is done https://github.com/radiovisual/keeli/issues/3
public getPrintSummary() {
let summary = ["\n"];
public getTableRow(problem: Problem): Array<Cell> {
const {
severity,
isIgnored,
ruleMeta,
locale,
message,
expected,
received,
} = problem;

summary.push(`Error(s) found: ${this.problemStore.getErrorCount()}`);
let items: Array<
string | HorizontalTableRow | VerticalTableRow | CrossTableRow | Cell
> = [];
let colSpan = 0;

if (this.problemStore.getIgnoredConfigurationProblemsCount() > 0) {
summary.push(
`Ignored Configuration Errors(s): ${this.problemStore.getIgnoredConfigurationProblemsCount()}`
);
if (severity === SEVERITY_LEVEL.error) {
if (isIgnored) {
items.push(chalk.red.strikethrough("error"));
} else {
items.push(chalk.red("error"));
}
} else if (severity === SEVERITY_LEVEL.warn) {
if (isIgnored) {
items.push(chalk.yellow.strikethrough("warn"));
} else {
items.push(chalk.yellow("warn"));
}
}

if (this.problemStore.getIgnoredValidationProblemsCount() > 0) {
summary.push(
`Ignored Validation Errors(s): ${this.problemStore.getIgnoredValidationProblemsCount()}`
);
if (locale) {
items.push(chalk.dim(locale));
colSpan++;
}

let messageWitDiff = isIgnored
? `${chalk.yellow("[ignored]")} ${message}`
: message;

if (expected || received) {
messageWitDiff += "\n\n";
}

if (expected) {
messageWitDiff += `${chalk.cyan("Expected")}: ${expected}\n`;
}

if (received) {
messageWitDiff += `${chalk.magenta("Received")}: ${received}\n`;
}

if (this.problemStore.getIgnoredErrorCount() > 0) {
summary.push(
`Ignored Errors: ${this.problemStore.getIgnoredErrorCount()}`
items.push(messageWitDiff);
items.push(ruleMeta.name);

return items as Cell[];
}

public getNewTable(useBorders = true) {
if (useBorders) {
return new Table();
}

return new Table({
chars: {
top: "",
"top-mid": "",
"top-left": "",
"top-right": "",
bottom: "",
"bottom-mid": "",
"bottom-left": "",
"bottom-right": "",
left: "",
"left-mid": "",
mid: "",
"mid-mid": "",
right: "",
"right-mid": "",
middle: " ",
},
style: { "padding-left": 0, "padding-right": 0 },
});
}

public getPrintSummary() {
const summaryTable = this.getNewTable(false);

const ignoredErrorCount = this.problemStore.getIgnoredErrorCount();
const errorCount = this.problemStore.getErrorCount() + ignoredErrorCount;

const ignoredWarningCount = this.problemStore.getIgnoredWarningCount();
const warningCount =
this.problemStore.getWarningCount() + ignoredWarningCount;

const errorSummary = [chalk.red("Errors:"), chalk.red(errorCount)];

if (ignoredErrorCount > 0) {
errorSummary.push(
`${chalk.dim.italic("(" + ignoredErrorCount + " ignored)")}`
);
}

summary.push(`Warnings(s) found: ${this.problemStore.getWarningCount()}`);
const warningSummary = [
chalk.yellow("Warnings:"),
chalk.yellow(warningCount),
];

if (this.problemStore.getIgnoredWarningCount() > 0) {
summary.push(
`Ignored Warnings: ${this.problemStore.getIgnoredWarningCount()}`
if (ignoredWarningCount > 0) {
warningSummary.push(
`${chalk.dim.italic("(" + ignoredWarningCount + " ignored)")}`
);
}

return summary.join("\n");
summaryTable.push(errorSummary);
summaryTable.push(warningSummary);

return `\n\n${summaryTable.toString()}`;
}
}

Expand Down
Loading

0 comments on commit e975198

Please sign in to comment.