-
Notifications
You must be signed in to change notification settings - Fork 248
/
error.js
164 lines (144 loc) · 4.86 KB
/
error.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
const chalk = require("chalk");
const figures = require("figures");
const { findRuleByName } = require("../graph-utl/rule-set");
const wrapAndIndent = require("../utl/wrap-and-indent");
const utl = require("./utl/index.js");
const SEVERITY2CHALK = {
error: chalk.red,
warn: chalk.yellow,
info: chalk.cyan,
ignore: chalk.gray,
};
const EXTRA_PATH_INFORMATION_INDENT = 6;
function formatExtraPathInformation(pExtra) {
return "\n".concat(
wrapAndIndent(
pExtra.join(` ${figures.arrowRight} \n`),
EXTRA_PATH_INFORMATION_INDENT
)
);
}
function formatModuleViolation(pViolation) {
return chalk.bold(pViolation.from);
}
function formatDependencyViolation(pViolation) {
return `${chalk.bold(pViolation.from)} ${figures.arrowRight} ${chalk.bold(
pViolation.to
)}`;
}
function formatCycleViolation(pViolation) {
return `${chalk.bold(pViolation.from)} ${
figures.arrowRight
} ${formatExtraPathInformation(pViolation.cycle)}`;
}
function formatReachabilityViolation(pViolation) {
return `${chalk.bold(pViolation.from)} ${figures.arrowRight} ${chalk.bold(
pViolation.to
)}${formatExtraPathInformation(pViolation.via)}`;
}
function formatInstabilityViolation(pViolation) {
return `${formatDependencyViolation(pViolation)}\n${wrapAndIndent(
chalk.dim(
`instability: ${utl.formatPercentage(
pViolation.metrics.from.instability
)} ${figures.arrowRight} ${utl.formatPercentage(
pViolation.metrics.to.instability
)}`
),
EXTRA_PATH_INFORMATION_INDENT
)}`;
}
function formatViolation(pViolation) {
const lViolationType2Formatter = {
module: formatModuleViolation,
dependency: formatDependencyViolation,
cycle: formatCycleViolation,
reachability: formatReachabilityViolation,
instability: formatInstabilityViolation,
};
const lFormattedViolators = utl.formatViolation(
pViolation,
lViolationType2Formatter,
formatDependencyViolation
);
return (
`${SEVERITY2CHALK[pViolation.rule.severity](pViolation.rule.severity)} ${
pViolation.rule.name
}: ${lFormattedViolators}` +
`${
pViolation.comment
? `\n${wrapAndIndent(chalk.dim(pViolation.comment))}\n`
: ""
}`
);
}
function formatMeta(pMeta) {
return `${pMeta.error} errors, ${pMeta.warn} warnings`;
}
function sumMeta(pMeta) {
return pMeta.error + pMeta.warn + pMeta.info;
}
function formatSummary(pSummary) {
let lMessage = `\n${figures.cross} ${sumMeta(
pSummary
)} dependency violations (${formatMeta(pSummary)}). ${
pSummary.totalCruised
} modules, ${pSummary.totalDependenciesCruised} dependencies cruised.\n`;
return pSummary.error > 0 ? chalk.red(lMessage) : lMessage;
}
function addExplanation(pRuleSet, pLong) {
return pLong
? (pViolation) => ({
...pViolation,
comment: findRuleByName(pRuleSet, pViolation.rule.name)?.comment ?? "-",
})
: (pViolation) => pViolation;
}
function formatIgnoreWarning(pNumberOfIgnoredViolations) {
if (pNumberOfIgnoredViolations > 0) {
return chalk.yellow(
`${figures.warning} ${pNumberOfIgnoredViolations} known violations ignored. Run without --ignore-known to see them.\n`
);
}
return "";
}
function report(pResults, pLong) {
const lNonIgnorableViolations = pResults.summary.violations.filter(
(pViolation) => pViolation.rule.severity !== "ignore"
);
if (lNonIgnorableViolations.length === 0) {
return `\n${chalk.green(figures.tick)} no dependency violations found (${
pResults.summary.totalCruised
} modules, ${
pResults.summary.totalDependenciesCruised
} dependencies cruised)\n${formatIgnoreWarning(
pResults.summary.ignore
)}\n\n`;
}
return lNonIgnorableViolations
.reverse()
.map(addExplanation(pResults.summary.ruleSetUsed, pLong))
.reduce((pAll, pThis) => `${pAll} ${formatViolation(pThis)}\n`, "\n")
.concat(formatSummary(pResults.summary))
.concat(formatIgnoreWarning(pResults.summary.ignore))
.concat(`\n`);
}
/**
* Returns the results of a cruise in a text only format, reminiscent of how eslint
* prints to stdout:
* - for each violation a message stating the violation name and the to and from
* - a summary with total number of errors and warnings found, and the total
* number of files cruised
* @param {import("../../types/cruise-result").ICruiseResult} pResults -
* @param {any} pOptions - An object with options;
* {boolean} long - whether or not to include an explanation
* (/ comment) which each violation
* @returns {import("../../types/dependency-cruiser").IReporterOutput} - output: the formatted text in a string
* exitCode: the number of errors found
*/
module.exports = function error(pResults, pOptions) {
return {
output: report(pResults, (pOptions || {}).long),
exitCode: pResults.summary.error,
};
};