dependency-cruiser 18.2.0 → 18.3.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 +6 -6
- package/bin/depcruise-baseline.mjs +12 -5
- package/bin/{dependency-cruise.mjs → dependency-cruiser.mjs} +24 -14
- package/package.json +7 -7
- package/src/analyze/analyze-modules.mjs +5 -1
- package/src/analyze/index.mjs +1 -1
- package/src/analyze/soften-known-violations.mjs +4 -2
- package/src/analyze/summarize/summarize-options.mjs +2 -0
- package/src/cache/options-compatible.mjs +1 -0
- package/src/cli/index.mjs +11 -3
- package/src/cli/init-config/config-template.mjs +1 -1
- package/src/cli/init-config/write-run-scripts-to-manifest.mjs +7 -7
- package/src/cli/normalize-cli-options.mjs +63 -2
- package/src/extract/helpers.mjs +1 -0
- package/src/extract/swc/dependency-visitor.mjs +13 -2
- package/src/extract/swc/parse.mjs +14 -4
- package/src/extract/transpile/try-import-available.mjs +1 -1
- package/src/graph-utl/compare.mjs +113 -14
- package/src/main/options/normalize.mjs +9 -3
- package/src/main/report-wrap.mjs +4 -2
- package/src/meta.cjs +1 -1
- package/src/report/baseline.mjs +52 -10
- package/src/report/dot-webpage/dot-module.mjs +1 -1
- package/src/report/index.mjs +1 -0
- package/src/schema/configuration.validate.mjs +1 -1
- package/src/schema/cruise-result.validate.mjs +1 -1
- package/src/utl/try-import.mjs +1 -1
- package/types/dependency-cruiser.d.mts +6 -0
- package/types/options.d.mts +17 -1
- package/types/restrictions.d.mts +2 -2
- package/types/shared-types.d.mts +16 -13
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/** @import { IViolation } from "../../types/dependency-cruiser.mjs" */
|
|
2
2
|
/* eslint-disable no-magic-numbers */
|
|
3
|
+
const SEVERITY2MUMBER = new Map([
|
|
4
|
+
["error", 1],
|
|
5
|
+
["warn", 2],
|
|
6
|
+
["info", 3],
|
|
7
|
+
["ignore", 4],
|
|
8
|
+
]);
|
|
9
|
+
|
|
3
10
|
function severity2number(pSeverity) {
|
|
4
|
-
|
|
5
|
-
["error", 1],
|
|
6
|
-
["warn", 2],
|
|
7
|
-
["info", 3],
|
|
8
|
-
["ignore", 4],
|
|
9
|
-
]);
|
|
10
|
-
|
|
11
|
-
return lSeverity2Number.get(pSeverity) || -1;
|
|
11
|
+
return SEVERITY2MUMBER.get(pSeverity) || -1;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export function compareSeverities(pFirstSeverity, pSecondSeverity) {
|
|
@@ -71,15 +71,21 @@ function compareArrays(pFirstArray, pSecondArray) {
|
|
|
71
71
|
*
|
|
72
72
|
* @param {IViolation} pFirstViolation
|
|
73
73
|
* @param {IViolation} pSecondViolation
|
|
74
|
-
* @
|
|
74
|
+
* @param {boolean} pCompareSeverities
|
|
75
|
+
* @returns {number}
|
|
75
76
|
*/
|
|
76
77
|
// eslint-disable-next-line complexity
|
|
77
|
-
|
|
78
|
+
function compareViolationsBase(
|
|
79
|
+
pFirstViolation,
|
|
80
|
+
pSecondViolation,
|
|
81
|
+
pCompareSeverities,
|
|
82
|
+
) {
|
|
78
83
|
return (
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
(pCompareSeverities &&
|
|
85
|
+
compareSeverities(
|
|
86
|
+
pFirstViolation.rule.severity,
|
|
87
|
+
pSecondViolation.rule.severity,
|
|
88
|
+
)) ||
|
|
83
89
|
pFirstViolation.rule.name.localeCompare(pSecondViolation.rule.name) ||
|
|
84
90
|
pFirstViolation.from.localeCompare(pSecondViolation.from) ||
|
|
85
91
|
pFirstViolation.to.localeCompare(pSecondViolation.to) ||
|
|
@@ -96,6 +102,99 @@ export function compareViolations(pFirstViolation, pSecondViolation) {
|
|
|
96
102
|
);
|
|
97
103
|
}
|
|
98
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Compares violations on all relevant fields _excluding_ severity
|
|
107
|
+
*
|
|
108
|
+
* @param {IViolation} pFirstViolation
|
|
109
|
+
* @param {IViolation} pSecondViolation
|
|
110
|
+
* @returns {number}
|
|
111
|
+
*/
|
|
112
|
+
export function compareViolationsExSeverities(
|
|
113
|
+
pFirstViolation,
|
|
114
|
+
pSecondViolation,
|
|
115
|
+
) {
|
|
116
|
+
return compareViolationsBase(pFirstViolation, pSecondViolation, false);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Compares violations on all relevant fields _including_ severity
|
|
121
|
+
*
|
|
122
|
+
* @param {IViolation} pFirstViolation
|
|
123
|
+
* @param {IViolation} pSecondViolation
|
|
124
|
+
* @returns {number}
|
|
125
|
+
*/
|
|
126
|
+
export function compareViolations(pFirstViolation, pSecondViolation) {
|
|
127
|
+
return compareViolationsBase(pFirstViolation, pSecondViolation, true);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Compare two arrays of violations and return a diff by value.
|
|
132
|
+
*
|
|
133
|
+
* Use the project’s established scalar ordering, compareViolations(),
|
|
134
|
+
* rather than introducing a second comparison construct. This keeps the
|
|
135
|
+
* semantics in one place and makes the diff logic easier to maintain.
|
|
136
|
+
*
|
|
137
|
+
* @param {IViolation[]} pFirstViolationArray - First array of violations
|
|
138
|
+
* @param {IViolation[]} pSecondViolationArray - Second array of violations
|
|
139
|
+
* @returns {{
|
|
140
|
+
* new: IViolation[]; // only in the second array
|
|
141
|
+
* same: IViolation[]; // in both arrays
|
|
142
|
+
* old: IViolation[]; // only in the first array
|
|
143
|
+
* }}
|
|
144
|
+
*/
|
|
145
|
+
export function diffViolationArrays(
|
|
146
|
+
pFirstViolationArray,
|
|
147
|
+
pSecondViolationArray,
|
|
148
|
+
) {
|
|
149
|
+
const lFirstViolations = pFirstViolationArray.toSorted(
|
|
150
|
+
compareViolationsExSeverities,
|
|
151
|
+
);
|
|
152
|
+
const lSecondViolations = pSecondViolationArray.toSorted(
|
|
153
|
+
compareViolationsExSeverities,
|
|
154
|
+
);
|
|
155
|
+
const lNew = [];
|
|
156
|
+
const lSame = [];
|
|
157
|
+
const lOld = [];
|
|
158
|
+
let lFirstIndex = 0;
|
|
159
|
+
let lSecondIndex = 0;
|
|
160
|
+
|
|
161
|
+
while (
|
|
162
|
+
lFirstIndex < lFirstViolations.length ||
|
|
163
|
+
lSecondIndex < lSecondViolations.length
|
|
164
|
+
) {
|
|
165
|
+
if (lFirstIndex >= lFirstViolations.length) {
|
|
166
|
+
lNew.push(lSecondViolations[lSecondIndex]);
|
|
167
|
+
lSecondIndex += 1;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (lSecondIndex >= lSecondViolations.length) {
|
|
172
|
+
lOld.push(lFirstViolations[lFirstIndex]);
|
|
173
|
+
lFirstIndex += 1;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const lComparison = compareViolationsExSeverities(
|
|
178
|
+
lFirstViolations[lFirstIndex],
|
|
179
|
+
lSecondViolations[lSecondIndex],
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
if (lComparison === 0) {
|
|
183
|
+
lSame.push(lFirstViolations[lFirstIndex]);
|
|
184
|
+
lFirstIndex += 1;
|
|
185
|
+
lSecondIndex += 1;
|
|
186
|
+
} else if (lComparison < 0) {
|
|
187
|
+
lOld.push(lFirstViolations[lFirstIndex]);
|
|
188
|
+
lFirstIndex += 1;
|
|
189
|
+
} else {
|
|
190
|
+
lNew.push(lSecondViolations[lSecondIndex]);
|
|
191
|
+
lSecondIndex += 1;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return { new: lNew, same: lSame, old: lOld };
|
|
196
|
+
}
|
|
197
|
+
|
|
99
198
|
export function compareRules(pLeftRule, pRightRule) {
|
|
100
199
|
return (
|
|
101
200
|
compareSeverities(pLeftRule.severity, pRightRule.severity) ||
|
|
@@ -4,7 +4,6 @@ import defaults from "./defaults.mjs";
|
|
|
4
4
|
import { uniq } from "#utl/array-util.mjs";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* @import { ICruiseResult } from "../../../types/cruise-result.mjs";
|
|
8
7
|
* @import { ICruiseOptions, IFormatOptions } from "../../../types/options.mjs";
|
|
9
8
|
* @import { IStrictCruiseOptions, IStrictFormatOptions } from "../../../types/strict-options.mjs";
|
|
10
9
|
* @import { IForbiddenRuleType, IFlattenedRuleSet } from "../../../types/rule-set.mjs";
|
|
@@ -115,6 +114,13 @@ function ruleSetHasMetricsRule(pRuleSet) {
|
|
|
115
114
|
);
|
|
116
115
|
}
|
|
117
116
|
|
|
117
|
+
// TODO duplicated in ../report-wrap.mjs
|
|
118
|
+
function getReporterSection(pOutputType) {
|
|
119
|
+
return ["x-dot-webpage", "dot-webpage"].includes(pOutputType)
|
|
120
|
+
? "dot"
|
|
121
|
+
: pOutputType;
|
|
122
|
+
}
|
|
123
|
+
|
|
118
124
|
/**
|
|
119
125
|
*
|
|
120
126
|
* @param {ICruiseOptions} pOptions
|
|
@@ -122,8 +128,8 @@ function ruleSetHasMetricsRule(pRuleSet) {
|
|
|
122
128
|
*/
|
|
123
129
|
function reporterShowsMetrics(pOptions) {
|
|
124
130
|
return (
|
|
125
|
-
(pOptions.reporterOptions?.[pOptions?.outputType]
|
|
126
|
-
|
|
131
|
+
(pOptions.reporterOptions?.[getReporterSection(pOptions?.outputType)]
|
|
132
|
+
?.showMetrics ?? false) === true
|
|
127
133
|
);
|
|
128
134
|
}
|
|
129
135
|
|
package/src/main/report-wrap.mjs
CHANGED
|
@@ -44,9 +44,11 @@ function reSummarizeResults(pResult, pFormatOptions) {
|
|
|
44
44
|
modules: lModules,
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
// TODO duplicated in ./options/normalize.mjs
|
|
48
48
|
function getReporterSection(pOutputType) {
|
|
49
|
-
return
|
|
49
|
+
return ["x-dot-webpage", "dot-webpage"].includes(pOutputType)
|
|
50
|
+
? "dot"
|
|
51
|
+
: pOutputType;
|
|
50
52
|
}
|
|
51
53
|
|
|
52
54
|
/**
|
package/src/meta.cjs
CHANGED
package/src/report/baseline.mjs
CHANGED
|
@@ -1,24 +1,66 @@
|
|
|
1
|
+
import { diffViolationArrays } from "#graph-utl/compare.mjs";
|
|
2
|
+
/**
|
|
3
|
+
* @import { ICruiseResult, IReporterOutput } from "../../types/dependency-cruiser.mjs";
|
|
4
|
+
* @import { IViolation} from "../../types/violations.mjs"
|
|
5
|
+
* @import { BaselineModeType } from "../../types/options.mjs"
|
|
6
|
+
*/
|
|
7
|
+
|
|
1
8
|
const DEFAULT_JSON_INDENT = 2;
|
|
2
9
|
const EOL = "\n";
|
|
10
|
+
const BASELINE_DEFAULT_MODE = "full";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {IViolation[]} pKnownViolations
|
|
14
|
+
* @param {IViolation[]} pCurrentViolations
|
|
15
|
+
* @param {BaselineModeType} pMode
|
|
16
|
+
* @returns {IReporterOutput}
|
|
17
|
+
*/
|
|
18
|
+
function getBaseline(pKnownViolations, pCurrentViolations, pMode) {
|
|
19
|
+
const lReturnValue = {};
|
|
20
|
+
const lKnownViolations = pKnownViolations || [];
|
|
21
|
+
const lViolationArrayDiff = diffViolationArrays(
|
|
22
|
+
lKnownViolations,
|
|
23
|
+
pCurrentViolations,
|
|
24
|
+
);
|
|
25
|
+
let lViolationsToEmit = pCurrentViolations;
|
|
26
|
+
let lModeAddition = " (running in 'full' mode => added to the baseline)";
|
|
27
|
+
|
|
28
|
+
if (pMode === "shrink-only") {
|
|
29
|
+
lViolationsToEmit = lViolationArrayDiff.same;
|
|
30
|
+
lModeAddition =
|
|
31
|
+
" (running in 'shrink-only' mode => not added to the baseline)";
|
|
32
|
+
}
|
|
33
|
+
lReturnValue.meta =
|
|
34
|
+
`${EOL}baseline : ${lViolationsToEmit.length} violations${EOL}${EOL}` +
|
|
35
|
+
` new : ${lViolationArrayDiff.new.length}${lViolationArrayDiff.new.length > 0 ? lModeAddition : ""}${EOL}` +
|
|
36
|
+
` same : ${lViolationArrayDiff.same.length}${EOL}` +
|
|
37
|
+
` removed : ${lViolationArrayDiff.old.length}${EOL}`;
|
|
38
|
+
lReturnValue.output =
|
|
39
|
+
JSON.stringify(lViolationsToEmit, null, DEFAULT_JSON_INDENT) + EOL;
|
|
40
|
+
|
|
41
|
+
return lReturnValue;
|
|
42
|
+
}
|
|
3
43
|
|
|
4
44
|
/**
|
|
5
|
-
*
|
|
45
|
+
* Returns the current 'baseline' of violations, which can be used
|
|
6
46
|
*
|
|
7
|
-
* @param {
|
|
47
|
+
* @param {ICruiseResult} pCruiseResult -
|
|
8
48
|
* the output of a dependency-cruise adhering to dependency-cruiser's
|
|
9
49
|
* cruise result schema
|
|
10
|
-
* @returns {
|
|
11
|
-
* output:
|
|
50
|
+
* @returns {IReporterOutput} -
|
|
51
|
+
* output: known violations
|
|
52
|
+
* meta: information to print on a side channel (e.g. stderr)
|
|
12
53
|
* exitCode: 0
|
|
13
54
|
*/
|
|
14
55
|
export default function baseline(pCruiseResult) {
|
|
56
|
+
const { meta, output } = getBaseline(
|
|
57
|
+
pCruiseResult.summary.optionsUsed.knownViolations,
|
|
58
|
+
pCruiseResult.summary.violations,
|
|
59
|
+
pCruiseResult.summary.optionsUsed?.baseline?.mode ?? BASELINE_DEFAULT_MODE,
|
|
60
|
+
);
|
|
15
61
|
return {
|
|
16
|
-
output
|
|
17
|
-
|
|
18
|
-
pCruiseResult.summary.violations,
|
|
19
|
-
null,
|
|
20
|
-
DEFAULT_JSON_INDENT,
|
|
21
|
-
) + EOL,
|
|
62
|
+
output,
|
|
63
|
+
meta,
|
|
22
64
|
exitCode: 0,
|
|
23
65
|
};
|
|
24
66
|
}
|
|
@@ -63,7 +63,7 @@ function isAvailable(pOptions) {
|
|
|
63
63
|
export default function dotWebpage(pResults, pDotWebpageReporterOptions) {
|
|
64
64
|
if (!isAvailable(pDotWebpageReporterOptions)) {
|
|
65
65
|
throw new Error(
|
|
66
|
-
"GraphViz dot, which is required for the '
|
|
66
|
+
"GraphViz dot, which is required for the 'dot-webpage' reporter doesn't " +
|
|
67
67
|
"seem to be available on this system. See the GraphViz download page for " +
|
|
68
68
|
"instruction on how to get it on your system: https://www.graphviz.org/download/",
|
|
69
69
|
);
|
package/src/report/index.mjs
CHANGED