dependency-cruiser 10.8.0-beta-1 → 10.8.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": "10.8.0-beta-1",
3
+ "version": "10.8.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",
@@ -0,0 +1,9 @@
1
+ const getStabilityMetrics = require("./get-stability-metrics");
2
+ const { shouldDeriveMetrics } = require("./utl");
3
+
4
+ module.exports = function deriveMetrics(pModules, pOptions) {
5
+ if (shouldDeriveMetrics(pOptions)) {
6
+ return { folders: getStabilityMetrics(pModules) };
7
+ }
8
+ return {};
9
+ };
@@ -0,0 +1,13 @@
1
+ const { shouldDeriveMetrics } = require("./utl");
2
+
3
+ module.exports = function deriveModuleMetrics(pModules, pOptions) {
4
+ if (shouldDeriveMetrics(pOptions)) {
5
+ return pModules.map((pModule) => ({
6
+ ...pModule,
7
+ instability:
8
+ pModule.dependencies.length /
9
+ (pModule.dependents.length + pModule.dependencies.length) || 0,
10
+ }));
11
+ }
12
+ return pModules;
13
+ };
@@ -17,7 +17,12 @@ function foldersObject2folderArray(pObject) {
17
17
  }));
18
18
  }
19
19
 
20
+ function shouldDeriveMetrics(pOptions) {
21
+ return pOptions.metrics || pOptions.outputType === "metrics";
22
+ }
23
+
20
24
  module.exports = {
21
25
  getParentFolders,
22
26
  foldersObject2folderArray,
27
+ shouldDeriveMetrics,
23
28
  };
@@ -8,6 +8,7 @@ const addDependents = require("./derive/dependents");
8
8
  const deriveReachable = require("./derive/reachable");
9
9
  const addValidations = require("./add-validations");
10
10
  const softenKnownViolations = require("./soften-known-violations");
11
+ const deriveModuleMetrics = require("./derive/metrics/module");
11
12
 
12
13
  module.exports = function enrichModules(pModules, pOptions) {
13
14
  bus.emit("progress", "analyzing: cycles", { level: busLogLevels.INFO });
@@ -18,6 +19,10 @@ module.exports = function enrichModules(pModules, pOptions) {
18
19
  lModules = deriveOrphans(lModules);
19
20
  bus.emit("progress", "analyzing: reachables", { level: busLogLevels.INFO });
20
21
  lModules = deriveReachable(lModules, pOptions.ruleSet);
22
+ bus.emit("progress", "analyzing: calculating module metrics", {
23
+ level: busLogLevels.INFO,
24
+ });
25
+ lModules = deriveModuleMetrics(lModules, pOptions);
21
26
  bus.emit("progress", "analyzing: add focus (if any)", {
22
27
  level: busLogLevels.INFO,
23
28
  });
@@ -1,5 +1,5 @@
1
1
  const enrichModules = require("./enrich-modules");
2
- const deriveFolders = require("./derive/folders");
2
+ const deriveFolderMetrics = require("./derive/metrics/folder.js");
3
3
  const summarize = require("./summarize");
4
4
  const clearCaches = require("./clear-caches");
5
5
 
@@ -10,7 +10,7 @@ module.exports = function enrich(pModules, pOptions, pFileAndDirectoryArray) {
10
10
  clearCaches();
11
11
  return {
12
12
  modules: lModules,
13
- ...deriveFolders(lModules, pOptions),
13
+ ...deriveFolderMetrics(lModules, pOptions),
14
14
  summary: summarize(lModules, pOptions, pFileAndDirectoryArray),
15
15
  };
16
16
  };
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-1",
4
+ version: "10.8.0-beta-2",
5
5
  engines: {
6
6
  node: "^12.20||^14||>=16",
7
7
  },
@@ -5,49 +5,80 @@ const DECIMAL_BASE = 10;
5
5
  const METRIC_WIDTH = 4;
6
6
  const INSTABILITY_DECIMALS = 2;
7
7
  const YADDUM = DECIMAL_BASE ** INSTABILITY_DECIMALS;
8
+ const COMPONENT_HEADER = "name";
8
9
 
9
- function transformMetricsToTable(pMetrics) {
10
+ function getHeader(pMaxNameWidth) {
11
+ return `${COMPONENT_HEADER.padEnd(pMaxNameWidth)} ${"N".padStart(
12
+ METRIC_WIDTH + 1
13
+ )} ${"Ca".padStart(METRIC_WIDTH + 1)} ${"Ce".padStart(
14
+ METRIC_WIDTH + 1
15
+ )} ${"I".padEnd(METRIC_WIDTH + 1)}`;
16
+ }
17
+
18
+ function getDemarcationLine(pMaxNameWidth) {
19
+ return `${"-".repeat(pMaxNameWidth)} ${"-".repeat(
20
+ METRIC_WIDTH + 1
21
+ )} ${"-".repeat(METRIC_WIDTH + 1)} ${"-".repeat(
22
+ METRIC_WIDTH + 1
23
+ )} ${"-".repeat(METRIC_WIDTH + 1)}`;
24
+ }
25
+
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
+ });
40
+ }
41
+
42
+ function metricifyModule({ source, dependents, dependencies, instability }) {
43
+ return {
44
+ name: source,
45
+ moduleCount: 1,
46
+ afferentCouplings: dependents.length,
47
+ efferentCouplings: dependencies.length,
48
+ instability,
49
+ };
50
+ }
51
+
52
+ function metricsAreCalculable(pModule) {
53
+ return (
54
+ !pModule.coreModule &&
55
+ !pModule.couldNotResolve &&
56
+ !pModule.matchesDoNotFollow
57
+ );
58
+ }
59
+
60
+ function orderByInstability(pLeft, pRight) {
61
+ return pRight.instability - pLeft.instability;
62
+ }
63
+ function transformMetricsToTable({ modules, folders }) {
10
64
  // TODO: should probably use a table module for this (i.e. text-table)
11
- // to simplify this code; but for this poc not having a dependency (so it's
12
- // copy-n-pasteable from a gist) is more important
13
- const lMaxNameWidth = pMetrics
14
- .map((pMetric) => pMetric.name.length)
65
+ // to simplify this code
66
+ const lMaxNameWidth = folders
67
+ .map((pFolder) => pFolder.name.length)
68
+ .concat(modules.map((pModule) => pModule.source.length))
69
+ .concat(COMPONENT_HEADER.length)
15
70
  .sort((pLeft, pRight) => pLeft - pRight)
16
71
  .pop();
17
72
 
18
- return [
19
- chalk.bold(
20
- `${"folder".padEnd(lMaxNameWidth)} ${"N".padStart(
21
- METRIC_WIDTH + 1
22
- )} ${"Ca".padStart(METRIC_WIDTH + 1)} ${"Ce".padStart(
23
- METRIC_WIDTH + 1
24
- )} ${"I".padEnd(METRIC_WIDTH + 1)}`
25
- ),
26
- ]
27
- .concat(
28
- `${"-".repeat(lMaxNameWidth)} ${"-".repeat(
29
- METRIC_WIDTH + 1
30
- )} ${"-".repeat(METRIC_WIDTH + 1)} ${"-".repeat(
31
- METRIC_WIDTH + 1
32
- )} ${"-".repeat(METRIC_WIDTH + 1)}`
33
- )
73
+ return [chalk.bold(getHeader(lMaxNameWidth))]
74
+ .concat(getDemarcationLine(lMaxNameWidth))
34
75
  .concat(
35
- pMetrics.map((pMetric) => {
36
- return `${pMetric.name.padEnd(
37
- lMaxNameWidth,
38
- " "
39
- )} ${pMetric.moduleCount
40
- .toString(DECIMAL_BASE)
41
- .padStart(METRIC_WIDTH)} ${pMetric.afferentCouplings
42
- .toString(DECIMAL_BASE)
43
- .padStart(METRIC_WIDTH)} ${pMetric.efferentCouplings
44
- .toString(DECIMAL_BASE)
45
- .padStart(METRIC_WIDTH)} ${(
46
- Math.round(YADDUM * pMetric.instability) / YADDUM
47
- )
48
- .toString(DECIMAL_BASE)
49
- .padEnd(METRIC_WIDTH)}`;
50
- })
76
+ getMetricsTable(
77
+ folders
78
+ .concat(modules.filter(metricsAreCalculable).map(metricifyModule))
79
+ .sort(orderByInstability),
80
+ lMaxNameWidth
81
+ )
51
82
  )
52
83
  .join(os.EOL)
53
84
  .concat(os.EOL);
@@ -68,7 +99,7 @@ function transformMetricsToTable(pMetrics) {
68
99
  module.exports = (pCruiseResult) => {
69
100
  if (pCruiseResult.folders) {
70
101
  return {
71
- output: transformMetricsToTable(pCruiseResult.folders),
102
+ output: transformMetricsToTable(pCruiseResult),
72
103
  exitCode: 0,
73
104
  };
74
105
  } else {
@@ -47,6 +47,7 @@ module.exports = {
47
47
  items: { $ref: "#/definitions/RuleSummaryType" },
48
48
  },
49
49
  consolidated: { type: "boolean" },
50
+ instability: { type: "number" },
50
51
  },
51
52
  },
52
53
  ReachableType: {
@@ -106,6 +106,15 @@ export interface IModule {
106
106
  * purposes - it will not be present after a regular cruise.
107
107
  */
108
108
  consolidated?: boolean;
109
+ /**
110
+ * "number of dependents/ (number of dependents + number of dependencies)
111
+ * A measure for how stable the module is; ranging between 0 (completely
112
+ * stable module) to 1 (completely instable module). Derived from Uncle
113
+ * Bob's instability metric - but applied to a single module instead of
114
+ * to a group of them. This attribute is only present when dependency-cruiser
115
+ * was asked to calculate metrics.
116
+ */
117
+ instability?: number;
109
118
  }
110
119
 
111
120
  export interface IDependency {
@@ -1,12 +0,0 @@
1
- const getStabilityMetrics = require("./get-stability-metrics");
2
-
3
- function shouldDeriveFolders(pOptions) {
4
- return pOptions.metrics || pOptions.outputType === "metrics";
5
- }
6
-
7
- module.exports = function deriveFolders(pModules, pOptions) {
8
- if (shouldDeriveFolders(pOptions)) {
9
- return { folders: getStabilityMetrics(pModules) };
10
- }
11
- return {};
12
- };