dependency-cruiser 18.3.0 → 18.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/dependency-cruiser.mjs +2 -2
- package/package.json +1 -1
- package/src/analyze/summarize/get-stats.mjs +38 -3
- package/src/analyze/summarize/index.mjs +30 -6
- package/src/extract/swc/dependency-visitor.mjs +5 -1
- package/src/meta.cjs +1 -1
- package/src/report/azure-devops.mjs +6 -2
- package/src/report/baseline.mjs +22 -7
- package/src/report/error-html/error-html-template.mjs +2 -0
- package/src/report/error-html/index.mjs +84 -8
- package/src/report/error.mjs +62 -13
- package/src/report/markdown.mjs +17 -9
- package/src/report/null.mjs +6 -3
- package/src/report/teamcity.mjs +4 -1
- package/src/schema/configuration.validate.mjs +1 -1
- package/src/schema/cruise-result.validate.mjs +1 -1
- package/types/cruise-result.d.mts +14 -0
- package/types/options.d.mts +16 -2
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ a `.dependency-cruiser.js` configuration file attuned to your project[^1][^2].
|
|
|
45
45
|
If you don't want to use `npx`, but instead `pnpx` (from the `pnpm`
|
|
46
46
|
package manager) or `yarn` - please refer to that tool's documentation.
|
|
47
47
|
Particularly `pnpx` has semantics that differ from `npx` quite significantly
|
|
48
|
-
and that you want to be aware of before using it. In the
|
|
48
|
+
and that you want to be aware of before using it. In the meantime: `npx`
|
|
49
49
|
_should_ work even when you installed the dependency with a package manager
|
|
50
50
|
different from `npm`.
|
|
51
51
|
|
|
@@ -103,8 +103,8 @@ try {
|
|
|
103
103
|
.addOption(
|
|
104
104
|
new Option(
|
|
105
105
|
"--baseline-mode <mode>",
|
|
106
|
-
'"shrink-only" - remove fixed violations but don\'t add new ones; "full" (default) - replace everything',
|
|
107
|
-
).choices(["full", "shrink-only"]),
|
|
106
|
+
'"shrink-only" - remove fixed violations but don\'t add new ones; "format" - rewrite but add nor remove anything; "full" (default) - replace everything',
|
|
107
|
+
).choices(["full", "shrink-only", "format"]),
|
|
108
108
|
)
|
|
109
109
|
.option(
|
|
110
110
|
"--ignore-known [file]",
|
package/package.json
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import { diffViolationArrays } from "#graph-utl/compare.mjs";
|
|
2
|
+
/**
|
|
3
|
+
* @import { IViolation } from "../../../types/violations.mjs"
|
|
4
|
+
* @import { IModule } from "../../../types/cruise-result.d.mts"
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {IViolation[]} pViolations
|
|
9
|
+
* @returns {{error:number; warn: number; info: number; ignore:number; }}
|
|
10
|
+
*/
|
|
11
|
+
export function getViolationCounts(pViolations) {
|
|
2
12
|
return pViolations.reduce(
|
|
3
13
|
(pAll, pThis) => {
|
|
4
14
|
pAll[pThis.rule.severity] += 1;
|
|
@@ -13,13 +23,38 @@ export function getViolationStats(pViolations) {
|
|
|
13
23
|
);
|
|
14
24
|
}
|
|
15
25
|
|
|
16
|
-
|
|
26
|
+
/**
|
|
27
|
+
* @param {IModule[]} pModules
|
|
28
|
+
* @returns {number} number of modules cruised
|
|
29
|
+
*/
|
|
30
|
+
export function getModulesCruisedCount(pModules) {
|
|
17
31
|
return pModules.length;
|
|
18
32
|
}
|
|
19
33
|
|
|
20
|
-
|
|
34
|
+
/**
|
|
35
|
+
* @param {IModule[]} pModules
|
|
36
|
+
* @returns {number} number of dependencies cruised
|
|
37
|
+
*/
|
|
38
|
+
export function getDependenciesCruisedCount(pModules) {
|
|
21
39
|
return pModules.reduce(
|
|
22
40
|
(pAll, pModule) => pAll + pModule.dependencies.length,
|
|
23
41
|
0,
|
|
24
42
|
);
|
|
25
43
|
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {IViolation[]} pKnownViolations
|
|
47
|
+
* @param {IViolation[]} pCurrentViolations
|
|
48
|
+
* @returns {{baselineSize:number; baselineStale:number; }}
|
|
49
|
+
*/
|
|
50
|
+
export function getBaselineDiffCounts(pKnownViolations, pCurrentViolations) {
|
|
51
|
+
const lViolationArrayDiff = diffViolationArrays(
|
|
52
|
+
pKnownViolations,
|
|
53
|
+
pCurrentViolations,
|
|
54
|
+
);
|
|
55
|
+
return {
|
|
56
|
+
baselineSize: pKnownViolations.length,
|
|
57
|
+
baselineStale: lViolationArrayDiff.old.length,
|
|
58
|
+
// lViolationArrayDiff.same.length is already present in the ignore attribute
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -4,9 +4,10 @@ import summarizeModules from "./summarize-modules.mjs";
|
|
|
4
4
|
import summarizeFolders from "./summarize-folders.mjs";
|
|
5
5
|
import summarizeOptions from "./summarize-options.mjs";
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
getViolationCounts,
|
|
8
|
+
getModulesCruisedCount,
|
|
9
|
+
getDependenciesCruisedCount,
|
|
10
|
+
getBaselineDiffCounts,
|
|
10
11
|
} from "./get-stats.mjs";
|
|
11
12
|
import { compareViolations } from "#graph-utl/compare.mjs";
|
|
12
13
|
import { getEnvironmentInfo } from "#environment.mjs";
|
|
@@ -118,6 +119,17 @@ function determineEnvironmentIssues(pOptions, pAvailableTranspilers) {
|
|
|
118
119
|
return lIssues.length > 0 ? { issues: lIssues } : {};
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
function getAdvisedExitCode(
|
|
123
|
+
pErrorCount,
|
|
124
|
+
pBaselineStaleCount,
|
|
125
|
+
pStaleEntriesSeverity,
|
|
126
|
+
) {
|
|
127
|
+
if ((pStaleEntriesSeverity ?? "warn") === "error") {
|
|
128
|
+
return pErrorCount + (pBaselineStaleCount ?? 0);
|
|
129
|
+
}
|
|
130
|
+
return pErrorCount;
|
|
131
|
+
}
|
|
132
|
+
|
|
121
133
|
/**
|
|
122
134
|
*
|
|
123
135
|
* @param {IModule[]} pModules -
|
|
@@ -149,11 +161,23 @@ export default function summarize(
|
|
|
149
161
|
...lEnvironment,
|
|
150
162
|
...determineEnvironmentIssues(pOptions, lEnvironment.transpilersFound),
|
|
151
163
|
};
|
|
164
|
+
const lViolationCounts = getViolationCounts(lViolations);
|
|
165
|
+
const lBaselineDiffCounts = pOptions.knownViolations
|
|
166
|
+
? getBaselineDiffCounts(pOptions.knownViolations, lViolations)
|
|
167
|
+
: {};
|
|
168
|
+
const lAdvisedExitCode = getAdvisedExitCode(
|
|
169
|
+
lViolationCounts.error,
|
|
170
|
+
lBaselineDiffCounts?.baselineStale,
|
|
171
|
+
pOptions?.baseline?.staleEntriesSeverity,
|
|
172
|
+
);
|
|
173
|
+
|
|
152
174
|
return {
|
|
153
175
|
violations: lViolations,
|
|
154
|
-
...
|
|
155
|
-
|
|
156
|
-
|
|
176
|
+
...lViolationCounts,
|
|
177
|
+
...lBaselineDiffCounts,
|
|
178
|
+
advisedExitCode: lAdvisedExitCode,
|
|
179
|
+
totalCruised: getModulesCruisedCount(pModules),
|
|
180
|
+
totalDependenciesCruised: getDependenciesCruisedCount(pModules),
|
|
157
181
|
...summarizeOptions(pFileDirectoryArray, pOptions),
|
|
158
182
|
...(pOptions.ruleSet ? { ruleSetUsed: addRuleSetUsed(pOptions) } : {}),
|
|
159
183
|
environment: lEnvironmentWithIssues,
|
|
@@ -4,10 +4,14 @@ import tryImport from "#utl/try-import.mjs";
|
|
|
4
4
|
import meta from "#meta.cjs";
|
|
5
5
|
|
|
6
6
|
/** @type {import('@swc/core/Visitor')} */
|
|
7
|
-
const
|
|
7
|
+
const lSwcVisitorModule = await tryImport(
|
|
8
8
|
"@swc/core/Visitor.js",
|
|
9
9
|
meta.supportedTranspilers.swc,
|
|
10
10
|
);
|
|
11
|
+
// under bun lSwcVisitorModule resolves to something different
|
|
12
|
+
// as under node.js - see https://github.com/sverweij/dependency-cruiser/issues/1092
|
|
13
|
+
// for details. In order to enable running dependency-cruiser on both:
|
|
14
|
+
const Visitor = lSwcVisitorModule.Visitor ?? lSwcVisitorModule;
|
|
11
15
|
|
|
12
16
|
function pryStringsFromArguments(pArguments) {
|
|
13
17
|
let lReturnValue = null;
|
package/src/meta.cjs
CHANGED
|
@@ -154,7 +154,8 @@ function formatResultMessage(pSummary) {
|
|
|
154
154
|
*/
|
|
155
155
|
function formatSummary(pSummary) {
|
|
156
156
|
return `##vso[task.complete result=${formatResultStatus(
|
|
157
|
-
|
|
157
|
+
// see below on the why of the fallback
|
|
158
|
+
pSummary.advisedExitCode ?? pSummary.error,
|
|
158
159
|
)};]${formatResultMessage(pSummary)}${EOL}`;
|
|
159
160
|
}
|
|
160
161
|
|
|
@@ -180,6 +181,9 @@ export default function azureDevOps(pResults) {
|
|
|
180
181
|
.map(formatViolation)
|
|
181
182
|
.join("")
|
|
182
183
|
.concat(formatSummary(pResults.summary)),
|
|
183
|
-
|
|
184
|
+
// advisedExitCode is a mandatory attribute as of dependency-cruiser 18.4.0
|
|
185
|
+
// however, this reporter can still encounter dependency-cruiser results
|
|
186
|
+
// from before that, hence the fallback
|
|
187
|
+
exitCode: pResults.summary.advisedExitCode ?? pResults.summary.error,
|
|
184
188
|
};
|
|
185
189
|
}
|
package/src/report/baseline.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { diffViolationArrays } from "#graph-utl/compare.mjs";
|
|
1
|
+
import { compareViolations, diffViolationArrays } from "#graph-utl/compare.mjs";
|
|
2
2
|
/**
|
|
3
3
|
* @import { ICruiseResult, IReporterOutput } from "../../types/dependency-cruiser.mjs";
|
|
4
4
|
* @import { IViolation} from "../../types/violations.mjs"
|
|
@@ -23,20 +23,35 @@ function getBaseline(pKnownViolations, pCurrentViolations, pMode) {
|
|
|
23
23
|
pCurrentViolations,
|
|
24
24
|
);
|
|
25
25
|
let lViolationsToEmit = pCurrentViolations;
|
|
26
|
-
let
|
|
26
|
+
let lModeAdditionTotal = "";
|
|
27
|
+
let lModeAdditionNew = " (running in 'full' mode => added to the baseline)";
|
|
28
|
+
let lModeAdditionOld =
|
|
29
|
+
" (running in 'full' mode => removed from the baseline)";
|
|
27
30
|
|
|
28
31
|
if (pMode === "shrink-only") {
|
|
29
32
|
lViolationsToEmit = lViolationArrayDiff.same;
|
|
30
|
-
|
|
33
|
+
lModeAdditionNew =
|
|
31
34
|
" (running in 'shrink-only' mode => not added to the baseline)";
|
|
35
|
+
lModeAdditionOld =
|
|
36
|
+
" (running in 'shrink-only' mode => removed from the baseline)";
|
|
37
|
+
}
|
|
38
|
+
if (pMode === "format") {
|
|
39
|
+
lViolationsToEmit = lKnownViolations;
|
|
40
|
+
lModeAdditionTotal = " (running in 'format' mode so no updates made)";
|
|
41
|
+
lModeAdditionNew = "";
|
|
42
|
+
lModeAdditionOld = "";
|
|
32
43
|
}
|
|
33
44
|
lReturnValue.meta =
|
|
34
|
-
`${EOL}baseline : ${lViolationsToEmit.length} violations${EOL}${EOL}` +
|
|
35
|
-
` new : ${lViolationArrayDiff.new.length}${lViolationArrayDiff.new.length > 0 ?
|
|
45
|
+
`${EOL}baseline : ${lViolationsToEmit.length} violations${lModeAdditionTotal}${EOL}${EOL}` +
|
|
46
|
+
` new : ${lViolationArrayDiff.new.length}${lViolationArrayDiff.new.length > 0 ? lModeAdditionNew : ""}${EOL}` +
|
|
36
47
|
` same : ${lViolationArrayDiff.same.length}${EOL}` +
|
|
37
|
-
`
|
|
48
|
+
` stale : ${lViolationArrayDiff.old.length}${lViolationArrayDiff.old.length > 0 ? lModeAdditionOld : ""}${EOL}`;
|
|
38
49
|
lReturnValue.output =
|
|
39
|
-
JSON.stringify(
|
|
50
|
+
JSON.stringify(
|
|
51
|
+
lViolationsToEmit.toSorted(compareViolations),
|
|
52
|
+
null,
|
|
53
|
+
DEFAULT_JSON_INDENT,
|
|
54
|
+
) + EOL;
|
|
40
55
|
|
|
41
56
|
return lReturnValue;
|
|
42
57
|
}
|
|
@@ -230,12 +230,14 @@ export default `<!DOCTYPE html>
|
|
|
230
230
|
<div style="float:left;padding-right:20px" class="ignore">
|
|
231
231
|
<strong>{{ignore}}</strong> ignored
|
|
232
232
|
</div>
|
|
233
|
+
{{staleDiv}}
|
|
233
234
|
|
|
234
235
|
</p>
|
|
235
236
|
{{violatedRulesTable}}
|
|
236
237
|
</span>
|
|
237
238
|
|
|
238
239
|
{{violationsList}}
|
|
240
|
+
{{baselineStaleTable}}
|
|
239
241
|
<footer>
|
|
240
242
|
<p><a href="https://github.com/sverweij/dependency-cruiser">{{depcruiseVersion}}</a> /
|
|
241
243
|
{{runDate}}</p>
|
|
@@ -6,6 +6,12 @@ import {
|
|
|
6
6
|
import template from "./error-html-template.mjs";
|
|
7
7
|
import meta from "#meta.cjs";
|
|
8
8
|
import { getOneLetterDependencyType } from "#report/utl/index.mjs";
|
|
9
|
+
import { diffViolationArrays } from "#graph-utl/compare.mjs";
|
|
10
|
+
/**
|
|
11
|
+
* @import { ICruiseResult, IViolation } from "../../../types/cruise-result.mjs"
|
|
12
|
+
* @import { IErrorReporterOptions } from "../../../types/reporter-options.mjs"
|
|
13
|
+
* @import { IReporterOutput } from "../../../types/dependency-cruiser.mjs"
|
|
14
|
+
*/
|
|
9
15
|
|
|
10
16
|
function getViolatedRuleRowClass(pViolatedRule) {
|
|
11
17
|
return pViolatedRule.unviolated ? ' class="unviolated"' : "";
|
|
@@ -34,7 +40,7 @@ function buildViolatedRuleRow(pViolatedRule) {
|
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
/**
|
|
37
|
-
* @param {
|
|
43
|
+
* @param {ICruiseResult} pResults
|
|
38
44
|
* @returns {string}
|
|
39
45
|
*/
|
|
40
46
|
function constructViolatedRulesTable(pResults) {
|
|
@@ -71,15 +77,17 @@ function constructViolatedRulesTable(pResults) {
|
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
/**
|
|
74
|
-
* @param {
|
|
80
|
+
* @param {IViolation} pViolation
|
|
75
81
|
* @returns {string}
|
|
76
82
|
*/
|
|
77
83
|
function getViolationRowClass(pViolation) {
|
|
78
84
|
return pViolation.rule.severity === "ignore" ? ' class="ignored"' : "";
|
|
79
85
|
}
|
|
86
|
+
|
|
80
87
|
/**
|
|
81
|
-
* @param {
|
|
82
|
-
* @
|
|
88
|
+
* @param {string} pPrefix
|
|
89
|
+
* @param {IErrorReporterOptions} pOptions
|
|
90
|
+
* @returns {(pViolation: IViolation) => string}
|
|
83
91
|
*/
|
|
84
92
|
function constructViolationRow(pPrefix, pOptions) {
|
|
85
93
|
return (pViolation) => {
|
|
@@ -101,7 +109,8 @@ function constructViolationRow(pPrefix, pOptions) {
|
|
|
101
109
|
}
|
|
102
110
|
|
|
103
111
|
/**
|
|
104
|
-
* @param {
|
|
112
|
+
* @param {ICruiseResult} pResults
|
|
113
|
+
* @param {IErrorReporterOptions} pOptions
|
|
105
114
|
* @returns {string}
|
|
106
115
|
*/
|
|
107
116
|
function constructViolationsList(pResults, pOptions) {
|
|
@@ -154,7 +163,68 @@ function constructViolationsList(pResults, pOptions) {
|
|
|
154
163
|
}
|
|
155
164
|
|
|
156
165
|
/**
|
|
157
|
-
* @param {
|
|
166
|
+
* @param {number} pBaselineStaleCount
|
|
167
|
+
* @returns {string}
|
|
168
|
+
*/
|
|
169
|
+
function constructStaleDiv(pBaselineStaleCount) {
|
|
170
|
+
if ((pBaselineStaleCount ?? 0) > 0) {
|
|
171
|
+
return `<div style="float:left;padding-right:20px" class="ignore">
|
|
172
|
+
<strong>${pBaselineStaleCount}</strong> stale entries in baseline
|
|
173
|
+
</div>`;
|
|
174
|
+
}
|
|
175
|
+
return "";
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* @param {ICruiseResult} pResults
|
|
180
|
+
* @param {IErrorReporterOptions} pOptions
|
|
181
|
+
* @returns {string}
|
|
182
|
+
*/
|
|
183
|
+
function constructBaselineStaleTable(pResults, pOptions) {
|
|
184
|
+
if ((pResults.summary.baselineStale ?? 0) > 0) {
|
|
185
|
+
const { old } = diffViolationArrays(
|
|
186
|
+
pResults.summary.optionsUsed.knownViolations,
|
|
187
|
+
pResults.summary.violations,
|
|
188
|
+
);
|
|
189
|
+
return `<span id="stale-baseline-entries">
|
|
190
|
+
<h2><svg class="p__svg--inline" viewBox="144 144 512 512" version="1.1" aria-hidden="true"><path d="M583.48 299.64a202 202 0 0 0-108.32-109.58 194.4 194.4 0 0 0-150.29 0 202.3 202.3 0 0 0-123.43 186.4v224.26a25.2 25.2 0 0 0 5.04 14.7q4.46.63 8.96.61c8.52.2 16.98-1.52 24.74-5.04a89 89 0 0 0 26.8-22.57c2.57-2.82 5.04-5.54 7.66-8.06 3.6-3.67 7.7-6.84 12.14-9.42a41 41 0 0 1 20.81-5.04c19.75 0 29.43 10.53 40.6 22.73a101 101 0 0 0 22.58 20.15 63 63 0 0 0 4.48 2.42 60.4 60.4 0 0 0 49.48 0q2.33-1.08 4.43-2.37c8.5-5.54 16.1-12.34 22.57-20.15 11.18-12.2 20.86-22.73 40.6-22.73A41 41 0 0 1 513.2 571a58 58 0 0 1 12.15 9.42 132 132 0 0 1 7.65 8.07 89 89 0 0 0 27 22.36 57 57 0 0 0 24.75 5.04q4.53 0 9.01-.6c3.2-4.25 4.95-9.4 5.04-14.71v-224.1a202 202 0 0 0-15.32-76.83zm0 124.74v176.33c-18.9-.45-28.41-10.73-39.35-22.67-2.42-2.62-5.04-5.34-7.5-7.96a83 83 0 0 0-11.44-9.73 55.4 55.4 0 0 0-32.8-10.07c-26.4 0-39.9 14.71-51.74 27.66s-20.9 23.02-40.65 23.02-29.43-10.53-40.61-22.72-25.2-27.66-51.74-27.66a55.4 55.4 0 0 0-32.75 10.08 83 83 0 0 0-11.44 9.72c-2.62 2.62-5.04 5.34-7.56 7.96-10.93 11.94-20.45 22.17-39.3 22.67V376.46c0-102.78 82.33-186.4 183.5-186.4 101.16 0 183.49 83.63 183.49 186.4z"/><path d="M511.69 280.75a59.6 59.6 0 1 0 59.6 63.83q.4-3.98 0-7.95a59.55 59.55 0 0 0-59.6-55.88m-44.53 59.65a44.45 44.45 0 0 1 66.1-38.84h-.91a38.92 38.92 0 0 0 0 77.84h.9a44.45 44.45 0 0 1-66.1-38.84zm-38.59-3.98a59.6 59.6 0 1 0 0 7.96q.4-3.99 0-7.96m-104.14 3.98a44.44 44.44 0 0 1 66.1-38.84h-.6a38.91 38.91 0 1 0 0 77.84h.9a44.45 44.45 0 0 1-66.4-39"/>
|
|
191
|
+
</svg> Stale entries in the baseline</h2>
|
|
192
|
+
<p>
|
|
193
|
+
These violations are in the baseline (typically <tt>.dependency-cruiser-known-violations.json</tt>),
|
|
194
|
+
but don't match any real violations anymore, e.g. because they were fixed in the meantime. You
|
|
195
|
+
can remove them with dependency-cruiser's
|
|
196
|
+
<a href="https://github.com/sverweij/dependency-cruiser/blob/main/doc/cli.md#--baseline-create-or-update-a-known-violations-baseline"><tt>--baseline --baseline-mode shrink-only</tt>
|
|
197
|
+
command line options</a>.
|
|
198
|
+
</p>
|
|
199
|
+
<table>
|
|
200
|
+
<thead>
|
|
201
|
+
<tr>
|
|
202
|
+
<th>severity</th>
|
|
203
|
+
<th>rule</th>
|
|
204
|
+
<th>from</th>
|
|
205
|
+
<th>types</th>
|
|
206
|
+
<th>to</th>
|
|
207
|
+
</tr>
|
|
208
|
+
</thead>
|
|
209
|
+
<tbody>
|
|
210
|
+
${old
|
|
211
|
+
.map(
|
|
212
|
+
constructViolationRow(
|
|
213
|
+
pResults.summary.optionsUsed.prefix ?? "",
|
|
214
|
+
pOptions,
|
|
215
|
+
),
|
|
216
|
+
)
|
|
217
|
+
.join("\n")}
|
|
218
|
+
</tbody>
|
|
219
|
+
</table>
|
|
220
|
+
</span>`;
|
|
221
|
+
}
|
|
222
|
+
return "";
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @param {ICruiseResult} pResults
|
|
227
|
+
* @param {IErrorReporterOptions} pOptions
|
|
158
228
|
* @returns {string}
|
|
159
229
|
*/
|
|
160
230
|
function report(pResults, pOptions) {
|
|
@@ -173,8 +243,13 @@ function report(pResults, pOptions) {
|
|
|
173
243
|
.replace("{{warn}}", pResults.summary.warn)
|
|
174
244
|
.replace("{{info}}", pResults.summary.info)
|
|
175
245
|
.replace("{{ignore}}", pResults.summary.ignore ?? 0)
|
|
246
|
+
.replace("{{staleDiv}}", constructStaleDiv(pResults.summary.baselineStale))
|
|
176
247
|
.replace("{{violatedRulesTable}}", constructViolatedRulesTable(pResults))
|
|
177
248
|
.replace("{{violationsList}}", constructViolationsList(pResults, lOptions))
|
|
249
|
+
.replace(
|
|
250
|
+
"{{baselineStaleTable}}",
|
|
251
|
+
constructBaselineStaleTable(pResults, pOptions),
|
|
252
|
+
)
|
|
178
253
|
.replace("{{depcruiseVersion}}", `dependency-cruiser@${meta.version}`)
|
|
179
254
|
.replace("{{runDate}}", new Date().toISOString());
|
|
180
255
|
}
|
|
@@ -182,8 +257,9 @@ function report(pResults, pOptions) {
|
|
|
182
257
|
/**
|
|
183
258
|
* Returns the results of a cruise in an 'incidence matrix'
|
|
184
259
|
*
|
|
185
|
-
* @param {
|
|
186
|
-
* @
|
|
260
|
+
* @param {ICruiseResult} pResults - the output of a dependency-cruise adhering to ../../schema/cruise-result.schema.json
|
|
261
|
+
* @param {IErrorReporterOptions} pOptions
|
|
262
|
+
* @returns {IReporterOutput} - output: an html program showing the summary & the violations (if any)
|
|
187
263
|
* exitCode: 0
|
|
188
264
|
*/
|
|
189
265
|
export default function errorHtml(pResults, pOptions) {
|
package/src/report/error.mjs
CHANGED
|
@@ -8,6 +8,13 @@ import {
|
|
|
8
8
|
import { findRuleByName } from "#graph-utl/rule-set.mjs";
|
|
9
9
|
import wrapAndIndent from "#utl/wrap-and-indent.mjs";
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* @import { ICruiseResult, IEnvironmentIssue } from "../../types/cruise-result.mjs"
|
|
13
|
+
* @import { IErrorReporterOptions } from "../../types/reporter-options.mjs"
|
|
14
|
+
* @import { IReporterOutput } from "../../types/dependency-cruiser.js"
|
|
15
|
+
* @import { SeverityType } from "../../types/shared-types.mjs"
|
|
16
|
+
*/
|
|
17
|
+
|
|
11
18
|
const SEVERITY2COLOR = new Map([
|
|
12
19
|
["error", "red"],
|
|
13
20
|
["warn", "yellow"],
|
|
@@ -114,6 +121,10 @@ function addExplanation(pRuleSet, pLong) {
|
|
|
114
121
|
: (pViolation) => pViolation;
|
|
115
122
|
}
|
|
116
123
|
|
|
124
|
+
/**
|
|
125
|
+
* @param {number} pNumberOfIgnoredViolations
|
|
126
|
+
* @returns {string}
|
|
127
|
+
*/
|
|
117
128
|
function formatIgnoreWarning(pNumberOfIgnoredViolations) {
|
|
118
129
|
if (pNumberOfIgnoredViolations > 0) {
|
|
119
130
|
return styleText(
|
|
@@ -123,8 +134,9 @@ function formatIgnoreWarning(pNumberOfIgnoredViolations) {
|
|
|
123
134
|
}
|
|
124
135
|
return "";
|
|
125
136
|
}
|
|
137
|
+
|
|
126
138
|
/**
|
|
127
|
-
* @param {
|
|
139
|
+
* @param {IEnvironmentIssue} pEnvironmentIssue
|
|
128
140
|
* @returns {string}
|
|
129
141
|
*/
|
|
130
142
|
function formatEnvironmentIssue(pEnvironmentIssue) {
|
|
@@ -135,7 +147,7 @@ function formatEnvironmentIssue(pEnvironmentIssue) {
|
|
|
135
147
|
}
|
|
136
148
|
|
|
137
149
|
/**
|
|
138
|
-
* @param {
|
|
150
|
+
* @param {IEnvironmentIssue[]} pEnvironmentIssues
|
|
139
151
|
* @returns {string}
|
|
140
152
|
*/
|
|
141
153
|
function formatEnvironmentIssues(pEnvironmentIssues) {
|
|
@@ -147,6 +159,30 @@ function formatEnvironmentIssues(pEnvironmentIssues) {
|
|
|
147
159
|
);
|
|
148
160
|
}
|
|
149
161
|
|
|
162
|
+
/**
|
|
163
|
+
* @param {number} pBaselineStaleCount
|
|
164
|
+
* @param {SeverityType} pStaleEntriesSeverity
|
|
165
|
+
* @returns {string}
|
|
166
|
+
*/
|
|
167
|
+
function formatStaleBaselineMessage(
|
|
168
|
+
pBaselineStaleCount,
|
|
169
|
+
pStaleEntriesSeverity,
|
|
170
|
+
) {
|
|
171
|
+
if ((pBaselineStaleCount ?? 0) > 0) {
|
|
172
|
+
const lStaleEntriesSeverity = pStaleEntriesSeverity ?? "warn";
|
|
173
|
+
return styleText(
|
|
174
|
+
SEVERITY2COLOR.get(lStaleEntriesSeverity),
|
|
175
|
+
`${SEVERITY2ICON.get(lStaleEntriesSeverity)} ${pBaselineStaleCount} stale known violations in the baseline. Run with '--baseline --baseline-mode shrink-only' to remove them.${EOL}`,
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
return "";
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @param {ICruiseResult} pResults
|
|
183
|
+
* @param {IErrorReporterOptions} pOptions
|
|
184
|
+
* @returns {string}
|
|
185
|
+
*/
|
|
150
186
|
function report(pResults, pOptions) {
|
|
151
187
|
const lOptions = {
|
|
152
188
|
long: false,
|
|
@@ -163,13 +199,20 @@ function report(pResults, pOptions) {
|
|
|
163
199
|
pResults.summary.totalCruised
|
|
164
200
|
} modules, ${
|
|
165
201
|
pResults.summary.totalDependenciesCruised
|
|
166
|
-
} dependencies cruised)${EOL}
|
|
167
|
-
pResults.summary.ignore
|
|
168
|
-
|
|
202
|
+
} dependencies cruised)${EOL}`
|
|
203
|
+
.concat(formatIgnoreWarning(pResults.summary.ignore))
|
|
204
|
+
.concat(
|
|
205
|
+
formatStaleBaselineMessage(
|
|
206
|
+
pResults.summary.baselineStale,
|
|
207
|
+
pResults.summary.optionsUsed?.baseline?.staleEntriesSeverity,
|
|
208
|
+
),
|
|
209
|
+
)
|
|
210
|
+
.concat(formatEnvironmentIssues(pResults.summary.environment?.issues))
|
|
211
|
+
.concat(EOL);
|
|
169
212
|
}
|
|
170
213
|
|
|
171
214
|
return lNonIgnorableViolations
|
|
172
|
-
.
|
|
215
|
+
.toReversed()
|
|
173
216
|
.map(addExplanation(pResults.summary.ruleSetUsed, lOptions.long))
|
|
174
217
|
.reduce(
|
|
175
218
|
(pAll, pThis) => `${pAll} ${formatViolation(pThis, lOptions)}${EOL}`,
|
|
@@ -177,6 +220,12 @@ function report(pResults, pOptions) {
|
|
|
177
220
|
)
|
|
178
221
|
.concat(formatSummary(pResults.summary))
|
|
179
222
|
.concat(formatIgnoreWarning(pResults.summary.ignore))
|
|
223
|
+
.concat(
|
|
224
|
+
formatStaleBaselineMessage(
|
|
225
|
+
pResults.summary.baselineStale,
|
|
226
|
+
pResults.summary.optionsUsed?.baseline?.staleEntriesSeverity,
|
|
227
|
+
),
|
|
228
|
+
)
|
|
180
229
|
.concat(formatEnvironmentIssues(pResults.summary.environment?.issues))
|
|
181
230
|
.concat(EOL);
|
|
182
231
|
}
|
|
@@ -187,16 +236,16 @@ function report(pResults, pOptions) {
|
|
|
187
236
|
* - for each violation a message stating the violation name and the to and from
|
|
188
237
|
* - a summary with total number of errors and warnings found, and the total
|
|
189
238
|
* number of files cruised
|
|
190
|
-
* @param {
|
|
191
|
-
* @param {
|
|
192
|
-
*
|
|
193
|
-
* (/ comment) which each violation
|
|
194
|
-
* @returns {import("../../types/dependency-cruiser.js").IReporterOutput} - output: the formatted text in a string
|
|
195
|
-
* exitCode: the number of errors found
|
|
239
|
+
* @param {ICruiseResult} pResults
|
|
240
|
+
* @param {IErrorReporterOptions} pOptions
|
|
241
|
+
* @returns {IReporterOutput}
|
|
196
242
|
*/
|
|
197
243
|
export default function error(pResults, pOptions) {
|
|
198
244
|
return {
|
|
199
245
|
output: report(pResults, pOptions || {}),
|
|
200
|
-
|
|
246
|
+
// advisedExitCode is a mandatory attribute as of dependency-cruiser 18.4.0
|
|
247
|
+
// however, this reporter can still encounter dependency-cruiser results
|
|
248
|
+
// from before that, hence the fallback
|
|
249
|
+
exitCode: pResults.summary.advisedExitCode ?? pResults.summary.error,
|
|
201
250
|
};
|
|
202
251
|
}
|
package/src/report/markdown.mjs
CHANGED
|
@@ -54,7 +54,18 @@ function severity2Icon(pSeverity) {
|
|
|
54
54
|
function formatStatsSummary(pSummary) {
|
|
55
55
|
const lSpacerLength = 4;
|
|
56
56
|
const lSpacer = " ".repeat(lSpacerLength);
|
|
57
|
-
return `**${pSummary.totalCruised}** modules${lSpacer}
|
|
57
|
+
return `**${pSummary.totalCruised}** modules${lSpacer}`
|
|
58
|
+
.concat(`**${pSummary.totalDependenciesCruised}** dependencies${lSpacer}`)
|
|
59
|
+
.concat(`**${pSummary.error}** errors${lSpacer}`)
|
|
60
|
+
.concat(`**${pSummary.warn}** warnings${lSpacer}`)
|
|
61
|
+
.concat(`**${pSummary.info}** informational${lSpacer}`)
|
|
62
|
+
.concat(`**${pSummary.ignore}** ignored`)
|
|
63
|
+
.concat(
|
|
64
|
+
(pSummary.baselineStale ?? 0) > 0
|
|
65
|
+
? `${lSpacer}**${pSummary.baselineStale}** stale entries in baseline`
|
|
66
|
+
: "",
|
|
67
|
+
)
|
|
68
|
+
.concat("\n");
|
|
58
69
|
}
|
|
59
70
|
|
|
60
71
|
/**
|
|
@@ -86,7 +97,7 @@ function formatRulesSummary(pCruiseResult, pIncludeIgnoredInSummary) {
|
|
|
86
97
|
/**
|
|
87
98
|
*
|
|
88
99
|
* @param {import("../../types/cruise-result.mjs").IViolation[]} pViolations
|
|
89
|
-
* @param {
|
|
100
|
+
* @param {import("../../types/reporter-options.mjs").IMarkdownReporterOptions} pOptions
|
|
90
101
|
* @returns {string}
|
|
91
102
|
*/
|
|
92
103
|
function formatViolations(pViolations, pOptions) {
|
|
@@ -108,19 +119,16 @@ function formatViolations(pViolations, pOptions) {
|
|
|
108
119
|
}, lTableHead);
|
|
109
120
|
}
|
|
110
121
|
|
|
111
|
-
function details(
|
|
122
|
+
function details(pViolations, pOptions) {
|
|
112
123
|
let lReturnValue = "";
|
|
113
|
-
if (
|
|
124
|
+
if (pViolations.length > 0) {
|
|
114
125
|
if (pOptions.showDetailsHeader) {
|
|
115
126
|
lReturnValue += `${pOptions.detailsHeader}\n\n`;
|
|
116
127
|
}
|
|
117
128
|
if (pOptions.collapseDetails) {
|
|
118
129
|
lReturnValue += `<details><summary>${pOptions.collapsedMessage}</summary>\n\n`;
|
|
119
130
|
}
|
|
120
|
-
lReturnValue += `${formatViolations(
|
|
121
|
-
pResults.summary.violations,
|
|
122
|
-
pOptions,
|
|
123
|
-
)}\n\n`;
|
|
131
|
+
lReturnValue += `${formatViolations(pViolations, pOptions)}\n\n`;
|
|
124
132
|
if (pOptions.collapseDetails) {
|
|
125
133
|
lReturnValue += "</details>\n\n";
|
|
126
134
|
}
|
|
@@ -165,7 +173,7 @@ function report(pResults, pOptions) {
|
|
|
165
173
|
}
|
|
166
174
|
|
|
167
175
|
if (lOptions.showDetails) {
|
|
168
|
-
lReturnValue += details(pResults, lOptions);
|
|
176
|
+
lReturnValue += details(pResults.summary.violations, lOptions);
|
|
169
177
|
}
|
|
170
178
|
|
|
171
179
|
if (lOptions.showFooter) {
|
package/src/report/null.mjs
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Returns the results of a cruise _only_ in an exitCode
|
|
3
3
|
*
|
|
4
|
-
* @param {import("../../types/cruise-result").ICruiseResult} pResults
|
|
5
|
-
* @returns {import("../../types/dependency-cruiser").IReporterOutput}
|
|
4
|
+
* @param {import("../../types/cruise-result.mjs").ICruiseResult} pResults
|
|
5
|
+
* @returns {import("../../types/dependency-cruiser.mjs").IReporterOutput}
|
|
6
6
|
*/
|
|
7
7
|
export default function nullReporter(pResults) {
|
|
8
8
|
return {
|
|
9
9
|
output: "",
|
|
10
|
-
|
|
10
|
+
// advisedExitCode is a mandatory attribute as of dependency-cruiser 18.4.0
|
|
11
|
+
// however, this reporter can still encounter dependency-cruiser results
|
|
12
|
+
// from before that, hence the fallback
|
|
13
|
+
exitCode: pResults.summary.advisedExitCode ?? pResults.summary.error,
|
|
11
14
|
};
|
|
12
15
|
}
|
package/src/report/teamcity.mjs
CHANGED
|
@@ -273,6 +273,9 @@ export default function teamcity(pResults) {
|
|
|
273
273
|
reportViolatedRules(lRuleSet, lViolations, lIgnoredCount, lFlowId)
|
|
274
274
|
.concat(reportViolations(lViolations, lIgnoredCount, lFlowId))
|
|
275
275
|
.reduce((pAll, pCurrent) => `${pAll}${pCurrent}${EOL}`, "") || EOL,
|
|
276
|
-
|
|
276
|
+
// advisedExitCode is a mandatory attribute as of dependency-cruiser 18.4.0
|
|
277
|
+
// however, this reporter can still encounter dependency-cruiser results
|
|
278
|
+
// from before that, hence the fallback
|
|
279
|
+
exitCode: pResults.summary.advisedExitCode ?? pResults.summary.error,
|
|
277
280
|
};
|
|
278
281
|
}
|