dependency-cruiser 10.8.0-beta-2 → 10.8.0-beta-3

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": "10.8.0-beta-2",
3
+ "version": "10.8.0-beta-3",
4
4
  "description": "Validate and visualize dependencies. With your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.",
5
5
  "keywords": [
6
6
  "static analysis",
@@ -1,13 +1,29 @@
1
+ // const { findModuleByName, clearCache } = require("../utl");
2
+ const { metricsAreCalculable } = require("./module-utl");
1
3
  const { shouldDeriveMetrics } = require("./utl");
2
4
 
3
5
  module.exports = function deriveModuleMetrics(pModules, pOptions) {
4
6
  if (shouldDeriveMetrics(pOptions)) {
5
7
  return pModules.map((pModule) => ({
6
8
  ...pModule,
7
- instability:
8
- pModule.dependencies.length /
9
- (pModule.dependents.length + pModule.dependencies.length) || 0,
9
+ ...(metricsAreCalculable(pModule)
10
+ ? {
11
+ instability:
12
+ pModule.dependencies.length /
13
+ (pModule.dependents.length + pModule.dependencies.length) || 0,
14
+ }
15
+ : {}),
10
16
  }));
17
+ // clearCache();
18
+ // return lModules.map((pModule) => ({
19
+ // ...pModule,
20
+ // dependencies: pModule.dependencies.map((pDependency) => ({
21
+ // ...pDependency,
22
+ // instability:
23
+ // (findModuleByName(lModules, pDependency.resolved) || {})
24
+ // .instability || 0,
25
+ // })),
26
+ // }));
11
27
  }
12
28
  return pModules;
13
29
  };
@@ -28,13 +28,18 @@ function reSummarizeResults(pResult, pFormatOptions) {
28
28
 
29
29
  module.exports = function reportWrap(pResult, pFormatOptions) {
30
30
  const lReportFunction = report.getReporter(pFormatOptions.outputType);
31
+ const lReportOptions = _get(
32
+ pResult,
33
+ `summary.optionsUsed.reporterOptions.${pFormatOptions.outputType}`,
34
+ {}
35
+ );
31
36
 
32
37
  return lReportFunction(
33
38
  reSummarizeResults(pResult, pFormatOptions),
34
39
  // passing format options here so reporters that read collapse patterns
35
40
  // from the result take the one passed in the format options instead
36
41
  _has(pFormatOptions, "collapse")
37
- ? { collapsePattern: pFormatOptions.collapse }
38
- : {}
42
+ ? { ...lReportOptions, collapsePattern: pFormatOptions.collapse }
43
+ : lReportOptions
39
44
  );
40
45
  };
package/src/meta.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /* generated - don't edit */
2
2
 
3
3
  module.exports = {
4
- version: "10.8.0-beta-2",
4
+ version: "10.8.0-beta-3",
5
5
  engines: {
6
6
  node: "^12.20||^14||>=16",
7
7
  },
@@ -1,4 +1,4 @@
1
- const os = require("os");
1
+ const { EOL } = require("os");
2
2
  const chalk = require("chalk");
3
3
 
4
4
  const DECIMAL_BASE = 10;
@@ -24,19 +24,24 @@ function getDemarcationLine(pMaxNameWidth) {
24
24
  }
25
25
 
26
26
  function getMetricsTable(pMetrics, pMaxNameWidth) {
27
- return pMetrics.map((pMetric) => {
28
- return `${pMetric.name.padEnd(pMaxNameWidth, " ")} ${pMetric.moduleCount
29
- .toString(DECIMAL_BASE)
30
- .padStart(METRIC_WIDTH)} ${pMetric.afferentCouplings
31
- .toString(DECIMAL_BASE)
32
- .padStart(METRIC_WIDTH)} ${pMetric.efferentCouplings
33
- .toString(DECIMAL_BASE)
34
- .padStart(METRIC_WIDTH)} ${(
35
- Math.round(YADDUM * pMetric.instability) / YADDUM
36
- )
37
- .toString(DECIMAL_BASE)
38
- .padEnd(METRIC_WIDTH)}`;
39
- });
27
+ return pMetrics.map(
28
+ ({
29
+ name,
30
+ moduleCount,
31
+ afferentCouplings,
32
+ efferentCouplings,
33
+ instability,
34
+ }) =>
35
+ `${name.padEnd(pMaxNameWidth, " ")} ${moduleCount
36
+ .toString(DECIMAL_BASE)
37
+ .padStart(METRIC_WIDTH)} ${afferentCouplings
38
+ .toString(DECIMAL_BASE)
39
+ .padStart(METRIC_WIDTH)} ${efferentCouplings
40
+ .toString(DECIMAL_BASE)
41
+ .padStart(METRIC_WIDTH)} ${(Math.round(YADDUM * instability) / YADDUM)
42
+ .toString(DECIMAL_BASE)
43
+ .padEnd(METRIC_WIDTH)}`
44
+ );
40
45
  }
41
46
 
42
47
  function metricifyModule({ source, dependents, dependencies, instability }) {
@@ -50,22 +55,33 @@ function metricifyModule({ source, dependents, dependencies, instability }) {
50
55
  }
51
56
 
52
57
  function metricsAreCalculable(pModule) {
53
- return (
54
- !pModule.coreModule &&
55
- !pModule.couldNotResolve &&
56
- !pModule.matchesDoNotFollow
57
- );
58
+ return Object.prototype.hasOwnProperty.call(pModule, "instability");
59
+ }
60
+
61
+ function orderByNumber(pAttributeName) {
62
+ // eslint-disable-next-line security/detect-object-injection
63
+ return (pLeft, pRight) => pRight[pAttributeName] - pLeft[pAttributeName];
58
64
  }
59
65
 
60
- function orderByInstability(pLeft, pRight) {
61
- return pRight.instability - pLeft.instability;
66
+ function orderByString(pAttributeName) {
67
+ return (pLeft, pRight) =>
68
+ // eslint-disable-next-line security/detect-object-injection
69
+ pLeft[pAttributeName].localeCompare(pRight[pAttributeName]);
62
70
  }
63
- function transformMetricsToTable({ modules, folders }) {
71
+
72
+ function transformMetricsToTable(
73
+ { modules, folders },
74
+ { orderBy, hideFolders, hideModules }
75
+ ) {
64
76
  // TODO: should probably use a table module for this (i.e. text-table)
65
77
  // to simplify this code
66
- const lMaxNameWidth = folders
67
- .map((pFolder) => pFolder.name.length)
68
- .concat(modules.map((pModule) => pModule.source.length))
78
+ let lComponents = [];
79
+ lComponents = lComponents.concat(hideFolders ? [] : folders);
80
+ lComponents = lComponents.concat(
81
+ hideModules ? [] : modules.filter(metricsAreCalculable).map(metricifyModule)
82
+ );
83
+ const lMaxNameWidth = lComponents
84
+ .map(({ name }) => name.length)
69
85
  .concat(COMPONENT_HEADER.length)
70
86
  .sort((pLeft, pRight) => pLeft - pRight)
71
87
  .pop();
@@ -74,20 +90,21 @@ function transformMetricsToTable({ modules, folders }) {
74
90
  .concat(getDemarcationLine(lMaxNameWidth))
75
91
  .concat(
76
92
  getMetricsTable(
77
- folders
78
- .concat(modules.filter(metricsAreCalculable).map(metricifyModule))
79
- .sort(orderByInstability),
93
+ lComponents
94
+ .sort(orderByString("name"))
95
+ .sort(orderByNumber(orderBy || "instability")),
80
96
  lMaxNameWidth
81
97
  )
82
98
  )
83
- .join(os.EOL)
84
- .concat(os.EOL);
99
+ .join(EOL)
100
+ .concat(EOL);
85
101
  }
86
102
 
87
103
  /**
88
- * Metrics plugin - to test the waters. If we want to use metrics in other
89
- * reporters - or use e.g. the Ca/ Ce/ I in rules (e.g. to detect violations
90
- * of Uncle Bob's variable dependency principle)
104
+ * returns stability metrics of modules & folders in an ascii table
105
+ *
106
+ * Potential future features:
107
+ * - additional output formats (csv?, html?)
91
108
  *
92
109
  * @param {import('../../types/dependency-cruiser').ICruiseResult} pCruiseResult -
93
110
  * the output of a dependency-cruise adhering to dependency-cruiser's
@@ -96,17 +113,18 @@ function transformMetricsToTable({ modules, folders }) {
96
113
  * output: some metrics on folders and dependencies
97
114
  * exitCode: 0
98
115
  */
99
- module.exports = (pCruiseResult) => {
116
+ module.exports = (pCruiseResult, pReporterOptions) => {
117
+ const lReporterOptions = pReporterOptions || {};
100
118
  if (pCruiseResult.folders) {
101
119
  return {
102
- output: transformMetricsToTable(pCruiseResult),
120
+ output: transformMetricsToTable(pCruiseResult, lReporterOptions),
103
121
  exitCode: 0,
104
122
  };
105
123
  } else {
106
124
  return {
107
125
  output:
108
- `${os.EOL}ERROR: The cruise result didn't contain any metrics - re-running the cruise with${os.EOL}` +
109
- ` the '--metrics' command line option should fix that.${os.EOL}${os.EOL}`,
126
+ `${EOL}ERROR: The cruise result didn't contain any metrics - re-running the cruise with${EOL}` +
127
+ ` the '--metrics' command line option should fix that.${EOL}${EOL}`,
110
128
  exitCode: 1,
111
129
  };
112
130
  }
@@ -394,6 +394,7 @@ module.exports = {
394
394
  dot: { $ref: "#/definitions/DotReporterOptionsType" },
395
395
  ddot: { $ref: "#/definitions/DotReporterOptionsType" },
396
396
  flat: { $ref: "#/definitions/DotReporterOptionsType" },
397
+ metrics: { $ref: "#/definitions/MetricsReporterOptionsType" },
397
398
  },
398
399
  },
399
400
  AnonReporterOptionsType: {
@@ -401,6 +402,24 @@ module.exports = {
401
402
  additionalProperties: false,
402
403
  properties: { wordlist: { type: "array", items: { type: "string" } } },
403
404
  },
405
+ MetricsReporterOptionsType: {
406
+ type: "object",
407
+ additionalProperties: false,
408
+ properties: {
409
+ orderBy: {
410
+ type: "string",
411
+ enum: [
412
+ "instability",
413
+ "moduleCount",
414
+ "afferentCouplings",
415
+ "efferentCouplings",
416
+ "name",
417
+ ],
418
+ },
419
+ hideModules: { type: "boolean" },
420
+ hideFolders: { type: "boolean" },
421
+ },
422
+ },
404
423
  DotReporterOptionsType: {
405
424
  type: "object",
406
425
  additionalProperties: false,
@@ -571,6 +571,7 @@ module.exports = {
571
571
  dot: { $ref: "#/definitions/DotReporterOptionsType" },
572
572
  ddot: { $ref: "#/definitions/DotReporterOptionsType" },
573
573
  flat: { $ref: "#/definitions/DotReporterOptionsType" },
574
+ metrics: { $ref: "#/definitions/MetricsReporterOptionsType" },
574
575
  },
575
576
  },
576
577
  AnonReporterOptionsType: {
@@ -578,6 +579,24 @@ module.exports = {
578
579
  additionalProperties: false,
579
580
  properties: { wordlist: { type: "array", items: { type: "string" } } },
580
581
  },
582
+ MetricsReporterOptionsType: {
583
+ type: "object",
584
+ additionalProperties: false,
585
+ properties: {
586
+ orderBy: {
587
+ type: "string",
588
+ enum: [
589
+ "instability",
590
+ "moduleCount",
591
+ "afferentCouplings",
592
+ "efferentCouplings",
593
+ "name",
594
+ ],
595
+ },
596
+ hideModules: { type: "boolean" },
597
+ hideFolders: { type: "boolean" },
598
+ },
599
+ },
581
600
  DotReporterOptionsType: {
582
601
  type: "object",
583
602
  additionalProperties: false,
@@ -21,6 +21,10 @@ export interface IReporterOptions {
21
21
  * Options to tweak the output of the flat /fdot reporter
22
22
  */
23
23
  flat?: IDotReporterOptions;
24
+ /**
25
+ * Options to tweak the output of the metrics reporter
26
+ */
27
+ metrics?: IMetricsReporterOptions;
24
28
  }
25
29
 
26
30
  export interface IReporterFiltersType {
@@ -96,3 +100,16 @@ export interface IDotThemeEntry {
96
100
  criteria: any;
97
101
  attributes: any;
98
102
  }
103
+
104
+ export interface IMetricsReporterOptions {
105
+ hideModules?: boolean;
106
+ hideFolders?: boolean;
107
+ oderBy?: MetricsOrderByType;
108
+ }
109
+
110
+ export type MetricsOrderByType =
111
+ | "instability"
112
+ | "moduleCount"
113
+ | "afferentCouplings"
114
+ | "efferentCouplings"
115
+ | "name";