dependency-cruiser 13.0.5 → 13.1.0-beta-2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dependency-cruiser",
3
- "version": "13.0.5",
3
+ "version": "13.1.0-beta-2",
4
4
  "description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
5
5
  "keywords": [
6
6
  "static analysis",
@@ -1,11 +1,10 @@
1
1
  import fs from "node:fs";
2
- import has from "lodash/has.js";
3
- import omit from "lodash/omit.js";
4
2
  import enhancedResolve from "enhanced-resolve";
3
+ import omit from "lodash/omit.js";
5
4
  import { scannableExtensions } from "../../extract/transpile/meta.mjs";
6
5
  import {
7
- ruleSetHasLicenseRule,
8
6
  ruleSetHasDeprecationRule,
7
+ ruleSetHasLicenseRule,
9
8
  } from "../../graph-utl/rule-set.mjs";
10
9
 
11
10
  const DEFAULT_CACHE_DURATION = 4000;
package/src/meta.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /* generated - don't edit */
2
2
 
3
3
  module.exports = {
4
- version: "13.0.5",
4
+ version: "13.1.0-beta-2",
5
5
  engines: {
6
6
  node: "^16.14||>=18",
7
7
  },
@@ -0,0 +1,222 @@
1
+ import { EOL } from "node:os";
2
+ import {
3
+ formatPercentage,
4
+ formatViolation as _formatViolation,
5
+ } from "./utl/index.mjs";
6
+
7
+ const SEVERITY2VSO_TYPE = new Map([
8
+ // "error" | "warn" | "info" | "ignore
9
+ ["error", "error"],
10
+ ["warn", "warning"],
11
+ // azure devops doesn't seem to understand 'info'. We still want to
12
+ // show them, though, hence:
13
+ ["info", "warning"],
14
+ ]);
15
+
16
+ /**
17
+ * @param {import("../../types/shared-types.js").SeverityType} pSeverity
18
+ * @returns {string}
19
+ */
20
+ function formatSeverity(pSeverity) {
21
+ return SEVERITY2VSO_TYPE.get(pSeverity) ?? "warning";
22
+ }
23
+
24
+ /**
25
+ * @param {import("../../types/violations.js").IViolation} pViolation
26
+ * @returns {string}
27
+ */
28
+ function formatModuleViolation(pViolation) {
29
+ return `${pViolation.rule.name}: ${pViolation.from}`;
30
+ }
31
+
32
+ /**
33
+ *
34
+ * @param {import("../../types/violations.js").IViolation} pViolation
35
+ * @returns {string}
36
+ */
37
+ function formatDependencyViolation(pViolation) {
38
+ return `${pViolation.rule.name}: ${pViolation.from} -> ${pViolation.to}`;
39
+ }
40
+
41
+ /**
42
+ * @param {import("../../types/violations.js").IViolation} pViolation
43
+ * @returns {string}
44
+ */
45
+ function formatCycleViolation(pViolation) {
46
+ return `${pViolation.rule.name}: ${
47
+ pViolation.from
48
+ } -> ${pViolation.cycle.join(" -> ")}`;
49
+ }
50
+
51
+ /**
52
+ * @param {import("../../types/violations.js").IViolation} pViolation
53
+ * @returns {string}
54
+ */
55
+ function formatReachabilityViolation(pViolation) {
56
+ return `${pViolation.rule.name}: ${pViolation.from} -> ${
57
+ pViolation.to
58
+ } (via ${pViolation.via.join(" -> ")})`;
59
+ }
60
+
61
+ /**
62
+ * @param {import("../../types/violations.js").IViolation} pViolation
63
+ * @returns {string}
64
+ */
65
+ function formatInstabilityViolation(pViolation) {
66
+ return `${pViolation.rule.name}: ${pViolation.from} -> ${
67
+ pViolation.to
68
+ } (instability: ${formatPercentage(
69
+ pViolation.metrics.from.instability
70
+ )} -> ${formatPercentage(pViolation.metrics.to.instability)})`;
71
+ }
72
+
73
+ /**
74
+ * @param {import("../../types/violations.js").IViolation} pViolation
75
+ * @returns {string}
76
+ */
77
+ function formatViolation(pViolation) {
78
+ const lViolationType2Formatter = {
79
+ module: formatModuleViolation,
80
+ dependency: formatDependencyViolation,
81
+ cycle: formatCycleViolation,
82
+ reachability: formatReachabilityViolation,
83
+ instability: formatInstabilityViolation,
84
+ };
85
+ let lFormattedViolators = _formatViolation(
86
+ pViolation,
87
+ lViolationType2Formatter,
88
+ formatDependencyViolation
89
+ );
90
+ return `##vso[task.logissue type=${formatSeverity(
91
+ pViolation.rule.severity
92
+ )};sourcepath=${pViolation.from}]${lFormattedViolators}${EOL}`;
93
+ }
94
+
95
+ /**
96
+ *
97
+ * @param {number} pNumberOfErrors
98
+ * @param {number} pNumberOfWarns
99
+ * @param {number} pNumberOfInfos
100
+ *
101
+ * @returns
102
+ */
103
+ function formatResultStatus(
104
+ pNumberOfErrors,
105
+ pNumberOfWarns,
106
+ pNumberOfInfos,
107
+ pNumberOfIgnored
108
+ ) {
109
+ if (pNumberOfErrors > 0) {
110
+ return "Failed";
111
+ }
112
+ if (pNumberOfWarns + pNumberOfInfos + pNumberOfIgnored > 0) {
113
+ return "SucceededWithIssues";
114
+ }
115
+ return "Succeeded";
116
+ }
117
+
118
+ function formatMeta(pMeta) {
119
+ const lWarningCount = pMeta.warn + pMeta.info;
120
+ const lError = `${pMeta.error} error`;
121
+ const lWarn = `${lWarningCount} warning/ informational`;
122
+ const lIgnore = (pMeta?.ignore ?? 0) > 0 ? `, ${pMeta.ignore} ignored` : "";
123
+
124
+ return `${lError}, ${lWarn}${lIgnore}`;
125
+ }
126
+
127
+ function sumMeta(pMeta) {
128
+ return pMeta.error + pMeta.warn + pMeta.info;
129
+ }
130
+
131
+ /**
132
+ *
133
+ * @param {number} pNumberOfIgnored
134
+ * @returns {string}
135
+ */
136
+ function formatIgnoreWarning(pNumberOfIgnored) {
137
+ return (pNumberOfIgnored ?? 0) > 0
138
+ ? ` - ${pNumberOfIgnored} violations ignored `
139
+ : "";
140
+ }
141
+
142
+ /**
143
+ *
144
+ * @param {import("../../types/cruise-result.js").ISummary} pSummary
145
+ */
146
+ function formatResultMessage(pSummary) {
147
+ let lStatSummary = `${pSummary.totalCruised} modules, ${
148
+ pSummary?.totalDependenciesCruised ?? 0
149
+ } dependencies cruised`;
150
+
151
+ if (sumMeta(pSummary) > 0) {
152
+ return `${sumMeta(pSummary)} dependency violations (${formatMeta(
153
+ pSummary
154
+ )}). ${lStatSummary}`;
155
+ } else {
156
+ return `no dependency violations found${formatIgnoreWarning(
157
+ pSummary.ignore
158
+ )} (${lStatSummary})`;
159
+ }
160
+ }
161
+
162
+ /**
163
+ *
164
+ * @param {import("../../types/cruise-result.js").ISummary} pSummary
165
+ */
166
+ function formatSummary(pSummary) {
167
+ return `##vso[task.complete result=${formatResultStatus(
168
+ pSummary.error,
169
+ pSummary.warn,
170
+ pSummary.info,
171
+ pSummary?.ignore ?? 0
172
+ )};]${formatResultMessage(pSummary)}${EOL}`;
173
+ }
174
+
175
+ /**
176
+ * Returns a bunch of Azure DevOps log messages:
177
+ * - for each violation in the passed results: the severity, source found, violated rule & some additional info
178
+ * - a summary line
179
+ *
180
+ * Background documentation:
181
+ * https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=bash#task-commands
182
+ *
183
+ * @param {import("../../types/dependency-cruiser.js").ICruiseResult} pResults
184
+ * @returns {import("../../types/dependency-cruiser.js").IReporterOutput}
185
+ */
186
+ // eslint-disable-next-line unicorn/prevent-abbreviations
187
+ export default function azureDevOps(pResults) {
188
+ const lViolations = (pResults?.summary?.violations ?? []).filter(
189
+ (pViolation) => pViolation.rule.severity !== "ignore"
190
+ );
191
+
192
+ return {
193
+ output: lViolations
194
+ .map(formatViolation)
195
+ .join("")
196
+ .concat(formatSummary(pResults.summary)),
197
+ exitCode: pResults.summary.error,
198
+ };
199
+ }
200
+
201
+ /*
202
+ Some notes from the documentation over at https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=bash#task-commands
203
+
204
+ Warnings and errors:
205
+
206
+ ##vso[task.logissue type=warning;sourcepath=consoleapp/main.cs;linenumber=1;columnnumber=1;code=100;]Found something that could be a problem.
207
+
208
+ Progress
209
+ ##vso[task.setprogress]current operation
210
+
211
+ Complete
212
+ ##vso[task.complete]current operation
213
+
214
+ Message grouping
215
+ ##[group]Beginning of a group
216
+ ##[warning]Warning message
217
+ ##[error]Error message
218
+ ##[section]Start of a section
219
+ ##[debug]Debug text
220
+ ##[command]Command-line being run
221
+ ##[endgroup]
222
+ */
@@ -1,27 +1,28 @@
1
1
  import { getExternalPluginReporter } from "./plugins.mjs";
2
2
 
3
- const TYPE2MODULE = {
4
- anon: "./anon/index.mjs",
5
- csv: "./csv.mjs",
6
- dot: "./dot/dot-module.mjs",
7
- ddot: "./dot/dot-folder.mjs",
8
- cdot: "./dot/dot-custom.mjs",
9
- archi: "./dot/dot-custom.mjs",
10
- fdot: "./dot/dot-flat.mjs",
11
- flat: "./dot/dot-flat.mjs",
12
- "err-html": "./error-html/index.mjs",
13
- markdown: "./markdown.mjs",
14
- "err-long": "./error-long.mjs",
15
- err: "./error.mjs",
16
- html: "./html/index.mjs",
17
- json: "./json.mjs",
18
- teamcity: "./teamcity.mjs",
19
- text: "./text.mjs",
20
- baseline: "./baseline.mjs",
21
- metrics: "./metrics.mjs",
22
- mermaid: "./mermaid.mjs",
23
- null: "./null.mjs",
24
- };
3
+ const TYPE2MODULE = new Map([
4
+ ["anon", "./anon/index.mjs"],
5
+ ["csv", "./csv.mjs"],
6
+ ["dot", "./dot/dot-module.mjs"],
7
+ ["ddot", "./dot/dot-folder.mjs"],
8
+ ["cdot", "./dot/dot-custom.mjs"],
9
+ ["archi", "./dot/dot-custom.mjs"],
10
+ ["fdot", "./dot/dot-flat.mjs"],
11
+ ["flat", "./dot/dot-flat.mjs"],
12
+ ["err-html", "./error-html/index.mjs"],
13
+ ["markdown", "./markdown.mjs"],
14
+ ["err-long", "./error-long.mjs"],
15
+ ["err", "./error.mjs"],
16
+ ["html", "./html/index.mjs"],
17
+ ["json", "./json.mjs"],
18
+ ["teamcity", "./teamcity.mjs"],
19
+ ["text", "./text.mjs"],
20
+ ["baseline", "./baseline.mjs"],
21
+ ["metrics", "./metrics.mjs"],
22
+ ["mermaid", "./mermaid.mjs"],
23
+ ["null", "./null.mjs"],
24
+ ["azure-devops", "./azure-devops.mjs"],
25
+ ]);
25
26
 
26
27
  /**
27
28
  * Returns the reporter function associated with given output type,
@@ -37,9 +38,7 @@ async function getReporter(pOutputType) {
37
38
  if (pOutputType?.startsWith("plugin:")) {
38
39
  lReturnValue = await getExternalPluginReporter(pOutputType);
39
40
  } else {
40
- const lModuleToImport =
41
- // eslint-disable-next-line security/detect-object-injection
42
- TYPE2MODULE[pOutputType] || "./identity.mjs";
41
+ const lModuleToImport = TYPE2MODULE.get(pOutputType) ?? "./identity.mjs";
43
42
  const lModule = await import(lModuleToImport);
44
43
  lReturnValue = lModule.default;
45
44
  }
@@ -52,7 +51,7 @@ async function getReporter(pOutputType) {
52
51
  * @returns {import("../../types/shared-types.js").OutputType[]} -
53
52
  */
54
53
  function getAvailableReporters() {
55
- return Object.keys(TYPE2MODULE);
54
+ return Array.from(TYPE2MODULE.keys());
56
55
  }
57
56
 
58
57
  export default {