dependency-cruiser 13.1.0-beta-1 → 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.1.0-beta-1",
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",
package/src/meta.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /* generated - don't edit */
2
2
 
3
3
  module.exports = {
4
- version: "13.1.0-beta-1",
4
+ version: "13.1.0-beta-2",
5
5
  engines: {
6
6
  node: "^16.14||>=18",
7
7
  },
@@ -1,25 +1,8 @@
1
- /*
2
- Message grouping
3
- ##[group]Beginning of a group
4
- ##[warning]Warning message
5
- ##[error]Error message
6
- ##[section]Start of a section
7
- ##[debug]Debug text
8
- ##[command]Command-line being run
9
- ##[endgroup]
10
-
11
- Warnings and errors:
12
-
13
- ##vso[task.logissue type=warning;sourcepath=consoleapp/main.cs;linenumber=1;columnnumber=1;code=100;]Found something that could be a problem.
14
-
15
- Progress
16
- ##vso[task.setprogress]current operation
17
-
18
- Complete
19
- ##vso[task.complete]current operation
20
- */
21
-
22
1
  import { EOL } from "node:os";
2
+ import {
3
+ formatPercentage,
4
+ formatViolation as _formatViolation,
5
+ } from "./utl/index.mjs";
23
6
 
24
7
  const SEVERITY2VSO_TYPE = new Map([
25
8
  // "error" | "warn" | "info" | "ignore
@@ -31,30 +14,149 @@ const SEVERITY2VSO_TYPE = new Map([
31
14
  ]);
32
15
 
33
16
  /**
34
- *
35
17
  * @param {import("../../types/shared-types.js").SeverityType} pSeverity
18
+ * @returns {string}
36
19
  */
37
20
  function formatSeverity(pSeverity) {
38
21
  return SEVERITY2VSO_TYPE.get(pSeverity) ?? "warning";
39
22
  }
40
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
+
41
32
  /**
42
33
  *
43
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}
44
76
  */
45
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
+ );
46
90
  return `##vso[task.logissue type=${formatSeverity(
47
91
  pViolation.rule.severity
48
- )};sourcepath=${pViolation.from}]${pViolation.rule.name}`;
92
+ )};sourcepath=${pViolation.from}]${lFormattedViolators}${EOL}`;
49
93
  }
50
94
 
51
95
  /**
52
96
  *
53
97
  * @param {number} pNumberOfErrors
98
+ * @param {number} pNumberOfWarns
99
+ * @param {number} pNumberOfInfos
100
+ *
54
101
  * @returns
55
102
  */
56
- function formatSuccess(pNumberOfErrors) {
57
- return pNumberOfErrors === 0 ? "Succeeded" : "Failed";
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
+ }
58
160
  }
59
161
 
60
162
  /**
@@ -62,16 +164,20 @@ function formatSuccess(pNumberOfErrors) {
62
164
  * @param {import("../../types/cruise-result.js").ISummary} pSummary
63
165
  */
64
166
  function formatSummary(pSummary) {
65
- return `##vso[task.complete result=${formatSuccess(pSummary.error)};] ${
66
- pSummary.totalCruised
67
- } modules, ${pSummary.totalDependenciesCruised} dependencies cruised`;
167
+ return `##vso[task.complete result=${formatResultStatus(
168
+ pSummary.error,
169
+ pSummary.warn,
170
+ pSummary.info,
171
+ pSummary?.ignore ?? 0
172
+ )};]${formatResultMessage(pSummary)}${EOL}`;
68
173
  }
69
174
 
70
175
  /**
71
176
  * Returns a bunch of Azure DevOps log messages:
72
- * - for each violated rule in the passed results: gnork
73
- * - for each violation in the passed results: bork
177
+ * - for each violation in the passed results: the severity, source found, violated rule & some additional info
178
+ * - a summary line
74
179
  *
180
+ * Background documentation:
75
181
  * https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=bash#task-commands
76
182
  *
77
183
  * @param {import("../../types/dependency-cruiser.js").ICruiseResult} pResults
@@ -79,25 +185,38 @@ function formatSummary(pSummary) {
79
185
  */
80
186
  // eslint-disable-next-line unicorn/prevent-abbreviations
81
187
  export default function azureDevOps(pResults) {
82
- // this is the documented way to get tsm to emit strings
83
- // Alternatively we could've used the 'low level API', which
84
- // involves creating new `Message`s and stringifying those.
85
- // The abstraction of the 'higher level API' makes this
86
- // reporter more easy to implement and maintain, despite
87
- // setting this property directly
88
-
89
188
  const lViolations = (pResults?.summary?.violations ?? []).filter(
90
189
  (pViolation) => pViolation.rule.severity !== "ignore"
91
190
  );
92
- const lIgnoredCount = pResults?.summary?.ignore ?? 0;
93
191
 
94
192
  return {
95
193
  output: lViolations
96
194
  .map(formatViolation)
97
- .join(EOL)
98
- .concat(EOL)
99
- .concat(formatSummary(pResults.summary))
100
- .concat(EOL),
195
+ .join("")
196
+ .concat(formatSummary(pResults.summary)),
101
197
  exitCode: pResults.summary.error,
102
198
  };
103
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,28 +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
- "azure-devops": "./azure-devops.mjs",
25
- };
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
+ ]);
26
26
 
27
27
  /**
28
28
  * Returns the reporter function associated with given output type,
@@ -38,9 +38,7 @@ async function getReporter(pOutputType) {
38
38
  if (pOutputType?.startsWith("plugin:")) {
39
39
  lReturnValue = await getExternalPluginReporter(pOutputType);
40
40
  } else {
41
- const lModuleToImport =
42
- // eslint-disable-next-line security/detect-object-injection
43
- TYPE2MODULE[pOutputType] || "./identity.mjs";
41
+ const lModuleToImport = TYPE2MODULE.get(pOutputType) ?? "./identity.mjs";
44
42
  const lModule = await import(lModuleToImport);
45
43
  lReturnValue = lModule.default;
46
44
  }
@@ -53,7 +51,7 @@ async function getReporter(pOutputType) {
53
51
  * @returns {import("../../types/shared-types.js").OutputType[]} -
54
52
  */
55
53
  function getAvailableReporters() {
56
- return Object.keys(TYPE2MODULE);
54
+ return Array.from(TYPE2MODULE.keys());
57
55
  }
58
56
 
59
57
  export default {