dependency-cruiser 10.8.0 → 11.2.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.
Files changed (54) hide show
  1. package/README.md +1 -1
  2. package/package.json +22 -16
  3. package/src/enrich/clear-caches.js +1 -1
  4. package/src/enrich/derive/circular/get-cycle.js +1 -1
  5. package/src/enrich/derive/dependents/get-dependents.js +1 -1
  6. package/src/enrich/derive/{metrics/get-stability-metrics.js → folders/aggregate-to-folders.js} +39 -30
  7. package/src/enrich/derive/folders/index.js +9 -0
  8. package/src/enrich/derive/folders/utl.js +44 -0
  9. package/src/enrich/derive/metrics/get-module-metrics.js +39 -0
  10. package/src/enrich/derive/metrics/index.js +14 -0
  11. package/src/enrich/derive/{utl.js → module-utl.js} +28 -0
  12. package/src/enrich/derive/orphan/is-orphan.js +1 -1
  13. package/src/enrich/derive/reachable/get-path.js +1 -1
  14. package/src/enrich/derive/reachable/index.js +1 -1
  15. package/src/enrich/enrich-modules.js +2 -2
  16. package/src/enrich/index.js +2 -2
  17. package/src/enrich/summarize/summarize-modules.js +24 -5
  18. package/src/extract/get-dependencies.js +11 -6
  19. package/src/extract/parse/to-typescript-ast.js +24 -8
  20. package/src/extract/utl/get-extension.js +9 -5
  21. package/src/main/options/normalize.js +28 -0
  22. package/src/meta.js +1 -1
  23. package/src/report/dot/dot.template.js +1 -1
  24. package/src/report/dot/index.js +7 -2
  25. package/src/report/dot/module-utl.js +47 -19
  26. package/src/report/dot/prepare-custom-level.js +2 -2
  27. package/src/report/dot/prepare-flat-level.js +2 -2
  28. package/src/report/dot/prepare-folder-level.js +2 -2
  29. package/src/report/error-html/error-html.template.js +1 -1
  30. package/src/report/error-html/utl.js +50 -7
  31. package/src/report/error.js +55 -21
  32. package/src/report/teamcity.js +37 -11
  33. package/src/report/utl/index.js +16 -0
  34. package/src/schema/baseline-violations.schema.js +1 -35
  35. package/src/schema/configuration.schema.js +1 -493
  36. package/src/schema/cruise-result.schema.js +1 -642
  37. package/src/utl/regex-util.js +57 -0
  38. package/src/validate/match-dependency-rule.js +19 -32
  39. package/src/validate/match-module-rule.js +1 -1
  40. package/src/validate/matchers.js +58 -48
  41. package/src/validate/violates-required-rule.js +1 -1
  42. package/types/baseline-violations.d.ts +1 -1
  43. package/types/cruise-result.d.ts +11 -50
  44. package/types/options.d.ts +5 -0
  45. package/types/reporter-options.d.ts +6 -0
  46. package/types/restrictions.d.ts +12 -0
  47. package/types/rule-summary.d.ts +23 -0
  48. package/types/shared-types.d.ts +7 -0
  49. package/types/violations.d.ts +43 -0
  50. package/src/enrich/derive/metrics/folder.js +0 -9
  51. package/src/enrich/derive/metrics/module-utl.js +0 -27
  52. package/src/enrich/derive/metrics/module.js +0 -29
  53. package/src/enrich/derive/metrics/utl.js +0 -28
  54. package/src/validate/utl.js +0 -31
@@ -0,0 +1,57 @@
1
+ /**
2
+ * If there is at least one group expression in the given pRulePath
3
+ * return the first matched one.
4
+ *
5
+ * Return null in all other cases.
6
+ *
7
+ * This fills our current need. Later we can expand it to return all group
8
+ * matches.
9
+ *
10
+ * @param {import("../../types/rule-set").IFromRestriction} pFromRestriction
11
+ * @param {string} pActualPath
12
+ * @returns {string[]|null}
13
+ */
14
+ function extractGroups(pFromRestriction, pActualPath) {
15
+ let lReturnValue = [];
16
+
17
+ if (Boolean(pFromRestriction.path)) {
18
+ let lMatchResult = pActualPath.match(pFromRestriction.path);
19
+
20
+ if (Boolean(lMatchResult) && lMatchResult.length > 1) {
21
+ lReturnValue = lMatchResult.filter(
22
+ (pResult) => typeof pResult === "string"
23
+ );
24
+ }
25
+ }
26
+ return lReturnValue;
27
+ }
28
+
29
+ /**
30
+ *
31
+ * Examples:
32
+ * replaceGroupPlaceholders("./src/components/$1", ["wholematch", "lala-component"]) =>
33
+ * './src/components/lala-component'
34
+ *
35
+ * replaceGroupPlaceholders("./test/components/$1/$2.spec.js$", ["wholematch", "lala-component", "things"]) =>
36
+ * './test/components/lala-component/things.spec.js$'
37
+ *
38
+ * @param {string} pString
39
+ * @param {string[]} pExtractedGroups - note that when using the result of a
40
+ * regex match, the 0th index contains the whole matched string and indices
41
+ * > 1 contain matched groups
42
+ * @returns {string} pString with the matching groups replaced with the
43
+ * groups from pExtractedgroups
44
+ */
45
+ function replaceGroupPlaceholders(pString, pExtractedGroups) {
46
+ return pExtractedGroups.reduce(
47
+ (pAll, pThis, pIndex) =>
48
+ // eslint-disable-next-line security/detect-non-literal-regexp
49
+ pAll.replace(new RegExp(`\\$${pIndex}`, "g"), pThis),
50
+ pString
51
+ );
52
+ }
53
+
54
+ module.exports = {
55
+ extractGroups,
56
+ replaceGroupPlaceholders,
57
+ };
@@ -1,25 +1,6 @@
1
- const _has = require("lodash/has");
1
+ const { extractGroups } = require("../utl/regex-util");
2
2
  const isModuleOnlyRule = require("./is-module-only-rule");
3
3
  const matchers = require("./matchers");
4
- const { extractGroups } = require("./utl");
5
-
6
- function propertyEquals(pTo, pRule, pProperty) {
7
- // ignore security/detect-object-injection because:
8
- // - we only use it from within the module with two fixed values
9
- // - the propertyEquals function is not exposed externaly
10
- return _has(pRule.to, pProperty)
11
- ? // eslint-disable-next-line security/detect-object-injection
12
- pTo[pProperty] === pRule.to[pProperty]
13
- : true;
14
- }
15
-
16
- function matchesMoreThanOneDependencyType(pRuleTo, pTo) {
17
- if (_has(pRuleTo, "moreThanOneDependencyType")) {
18
- return pRuleTo.moreThanOneDependencyType === pTo.dependencyTypes.length > 1;
19
- }
20
-
21
- return true;
22
- }
23
4
 
24
5
  function match(pFrom, pTo) {
25
6
  // eslint-disable-next-line complexity
@@ -33,22 +14,28 @@ function match(pFrom, pTo) {
33
14
  matchers.toPathNot(pRule, pTo, lGroups) &&
34
15
  matchers.toDependencyTypes(pRule, pTo) &&
35
16
  matchers.toDependencyTypesNot(pRule, pTo) &&
36
- matchesMoreThanOneDependencyType(pRule.to, pTo) &&
37
- matchers.toLicense(pRule, pTo) &&
38
- matchers.toLicenseNot(pRule, pTo) &&
39
- matchers.toExoticRequire(pRule, pTo) &&
40
- matchers.toExoticRequireNot(pRule, pTo) &&
41
- matchers.toVia(pRule, pTo) &&
42
- matchers.toViaNot(pRule, pTo) &&
17
+ matchers.matchesMoreThanOneDependencyType(pRule, pTo) &&
43
18
  // preCompilationOnly is not a mandatory attribute, but if the attribute
44
19
  // is in the rule but not in the dependency there won't be a match
45
20
  // anyway, so we can use the default propertyEquals method regardless
46
- propertyEquals(pTo, pRule, "preCompilationOnly") &&
21
+ matchers.propertyEquals(pRule, pTo, "preCompilationOnly") &&
47
22
  // couldNotResolve, circular, dynamic and exoticallyRequired _are_ mandatory
48
- propertyEquals(pTo, pRule, "couldNotResolve") &&
49
- propertyEquals(pTo, pRule, "circular") &&
50
- propertyEquals(pTo, pRule, "dynamic") &&
51
- propertyEquals(pTo, pRule, "exoticallyRequired")
23
+ matchers.propertyEquals(pRule, pTo, "couldNotResolve") &&
24
+ matchers.propertyEquals(pRule, pTo, "circular") &&
25
+ matchers.propertyEquals(pRule, pTo, "dynamic") &&
26
+ matchers.propertyEquals(pRule, pTo, "exoticallyRequired") &&
27
+ matchers.propertyMatches(pRule, pTo, "license", "license") &&
28
+ matchers.propertyMatchesNot(pRule, pTo, "licenseNot", "license") &&
29
+ matchers.propertyMatches(pRule, pTo, "exoticRequire", "exoticRequire") &&
30
+ matchers.propertyMatchesNot(
31
+ pRule,
32
+ pTo,
33
+ "exoticRequireNot",
34
+ "exoticRequire"
35
+ ) &&
36
+ matchers.toVia(pRule, pTo) &&
37
+ matchers.toViaNot(pRule, pTo) &&
38
+ matchers.toIsMoreUnstable(pRule, pFrom, pTo)
52
39
  );
53
40
  };
54
41
  }
@@ -1,7 +1,7 @@
1
1
  const _has = require("lodash/has");
2
+ const { extractGroups } = require("../utl/regex-util");
2
3
  const isModuleOnlyRule = require("./is-module-only-rule");
3
4
  const matchers = require("./matchers");
4
- const { extractGroups } = require("./utl");
5
5
 
6
6
  function matchesOrphanRule(pRule, pModule) {
7
7
  return (
@@ -1,4 +1,31 @@
1
+ /* eslint-disable security/detect-object-injection */
2
+ const _has = require("lodash/has");
1
3
  const { intersects } = require("../utl/array-util");
4
+ const { replaceGroupPlaceholders } = require("../utl/regex-util");
5
+
6
+ function propertyEquals(pRule, pDependency, pProperty) {
7
+ // The properties can be booleans, so we can't use !pRule.to[pProperty]
8
+ if (_has(pRule.to, pProperty)) {
9
+ return pDependency[pProperty] === pRule.to[pProperty];
10
+ }
11
+ return true;
12
+ }
13
+
14
+ function propertyMatches(pRule, pDependency, pRuleProperty, pProperty) {
15
+ return Boolean(
16
+ !pRule.to[pRuleProperty] ||
17
+ (pDependency[pProperty] &&
18
+ pDependency[pProperty].match(pRule.to[pRuleProperty]))
19
+ );
20
+ }
21
+
22
+ function propertyMatchesNot(pRule, pDependency, pRuleProperty, pProperty) {
23
+ return Boolean(
24
+ !pRule.to[pRuleProperty] ||
25
+ (pDependency[pProperty] &&
26
+ !pDependency[pProperty].match(pRule.to[pRuleProperty]))
27
+ );
28
+ }
2
29
 
3
30
  function fromPath(pRule, pModule) {
4
31
  return Boolean(!pRule.from.path || pModule.source.match(pRule.from.path));
@@ -20,20 +47,11 @@ function modulePathNot(pRule, pModule) {
20
47
  );
21
48
  }
22
49
 
23
- function _replaceGroupPlaceholders(pString, pExtractedGroups) {
24
- return pExtractedGroups.reduce(
25
- (pAll, pThis, pIndex) =>
26
- // eslint-disable-next-line security/detect-non-literal-regexp
27
- pAll.replace(new RegExp(`\\$${pIndex}`, "g"), pThis),
28
- pString
29
- );
30
- }
31
-
32
50
  function _toPath(pRule, pString, pGroups = []) {
33
51
  return Boolean(
34
52
  !pRule.to.path ||
35
53
  (pGroups.length > 0
36
- ? pString.match(_replaceGroupPlaceholders(pRule.to.path, pGroups))
54
+ ? pString.match(replaceGroupPlaceholders(pRule.to.path, pGroups))
37
55
  : pString.match(pRule.to.path))
38
56
  );
39
57
  }
@@ -50,7 +68,7 @@ function _toPathNot(pRule, pString, pGroups = []) {
50
68
  return (
51
69
  !Boolean(pRule.to.pathNot) ||
52
70
  !(pGroups.length > 0
53
- ? pString.match(_replaceGroupPlaceholders(pRule.to.pathNot, pGroups))
71
+ ? pString.match(replaceGroupPlaceholders(pRule.to.pathNot, pGroups))
54
72
  : pString.match(pRule.to.pathNot))
55
73
  );
56
74
  }
@@ -77,33 +95,11 @@ function toDependencyTypesNot(pRule, pDependency) {
77
95
  );
78
96
  }
79
97
 
80
- function toLicense(pRule, pDependency) {
81
- return Boolean(
82
- !pRule.to.license ||
83
- (pDependency.license && pDependency.license.match(pRule.to.license))
84
- );
85
- }
86
-
87
- function toLicenseNot(pRule, pDependency) {
88
- return Boolean(
89
- !pRule.to.licenseNot ||
90
- (pDependency.license && !pDependency.license.match(pRule.to.licenseNot))
91
- );
92
- }
93
-
94
- function toExoticRequire(pRule, pDependency) {
95
- return Boolean(
96
- !pRule.to.exoticRequire ||
97
- (pDependency.exoticRequire &&
98
- pDependency.exoticRequire.match(pRule.to.exoticRequire))
99
- );
100
- }
101
-
102
- function toExoticRequireNot(pRule, pDependency) {
98
+ function toVia(pRule, pDependency) {
103
99
  return Boolean(
104
- !pRule.to.exoticRequireNot ||
105
- (pDependency.exoticRequire &&
106
- !pDependency.exoticRequire.match(pRule.to.exoticRequireNot))
100
+ !pRule.to.via ||
101
+ (pDependency.cycle &&
102
+ pDependency.cycle.some((pVia) => pVia.match(pRule.to.via)))
107
103
  );
108
104
  }
109
105
 
@@ -115,16 +111,32 @@ function toViaNot(pRule, pDependency) {
115
111
  );
116
112
  }
117
113
 
118
- function toVia(pRule, pDependency) {
119
- return Boolean(
120
- !pRule.to.via ||
121
- (pDependency.cycle &&
122
- pDependency.cycle.some((pVia) => pVia.match(pRule.to.via)))
123
- );
114
+ function toIsMoreUnstable(pRule, pModule, pDependency) {
115
+ if (_has(pRule, "to.moreUnstable")) {
116
+ return (
117
+ (pRule.to.moreUnstable &&
118
+ pModule.instability < pDependency.instability) ||
119
+ (!pRule.to.moreUnstable && pModule.instability >= pDependency.instability)
120
+ );
121
+ }
122
+ return true;
123
+ }
124
+
125
+ function matchesMoreThanOneDependencyType(pRule, pDependency) {
126
+ if (_has(pRule.to, "moreThanOneDependencyType")) {
127
+ return (
128
+ pRule.to.moreThanOneDependencyType ===
129
+ pDependency.dependencyTypes.length > 1
130
+ );
131
+ }
132
+ return true;
124
133
  }
125
134
 
126
135
  module.exports = {
127
- _replaceGroupPlaceholders,
136
+ replaceGroupPlaceholders,
137
+ propertyEquals,
138
+ propertyMatches,
139
+ propertyMatchesNot,
128
140
  fromPath,
129
141
  fromPathNot,
130
142
  toPath,
@@ -135,10 +147,8 @@ module.exports = {
135
147
  toModulePathNot,
136
148
  toDependencyTypes,
137
149
  toDependencyTypesNot,
138
- toLicense,
139
- toLicenseNot,
140
- toExoticRequire,
141
- toExoticRequireNot,
142
150
  toVia,
143
151
  toViaNot,
152
+ toIsMoreUnstable,
153
+ matchesMoreThanOneDependencyType,
144
154
  };
@@ -1,5 +1,5 @@
1
+ const { extractGroups } = require("../utl/regex-util");
1
2
  const matchers = require("./matchers");
2
- const { extractGroups } = require("./utl");
3
3
 
4
4
  /**
5
5
  * Returns true if the module violates the rule.
@@ -1,3 +1,3 @@
1
- import { IViolation } from "./cruise-result";
1
+ import { IViolation } from "./violations";
2
2
 
3
3
  export type IBaselineViolations = IViolation[];
@@ -1,11 +1,8 @@
1
1
  import { ICruiseOptions } from "./options";
2
2
  import { IFlattenedRuleSet } from "./rule-set";
3
- import {
4
- DependencyType,
5
- ModuleSystemType,
6
- SeverityType,
7
- ProtocolType,
8
- } from "./shared-types";
3
+ import { DependencyType, ModuleSystemType, ProtocolType } from "./shared-types";
4
+ import { IViolation } from "./violations";
5
+ import { IRuleSummary } from "./rule-summary";
9
6
 
10
7
  export interface ICruiseResult {
11
8
  /**
@@ -224,27 +221,11 @@ export interface IDependency {
224
221
  * will be in the 'rule' object at the same level.
225
222
  */
226
223
  valid: boolean;
227
- }
228
-
229
- /**
230
- * If there was a rule violation (valid === false), this object contains the name of the
231
- * rule and severity of violating it.
232
- */
233
- export interface IRuleSummary {
234
224
  /**
235
- * The (short, eslint style) name of the violated rule. Typically something like
236
- * 'no-core-punycode' or 'no-outside-deps'.
225
+ * the (de-normalized) instability of the dependency - also available in
226
+ * the module on the 'to' side of this dependency
237
227
  */
238
- name: string;
239
- /**
240
- * How severe a violation of a rule is. The 'error' severity will make some reporters return
241
- * a non-zero exit code, so if you want e.g. a build to stop when there's a rule violated:
242
- * use that. The absence of the 'ignore' severity here is by design; ignored rules don't
243
- * show up in the output.
244
- *
245
- * Severity to use when a dependency is not in the 'allowed' set of rules. Defaults to 'warn'
246
- */
247
- severity: SeverityType;
228
+ instability: number;
248
229
  }
249
230
 
250
231
  export interface IReachable {
@@ -389,29 +370,6 @@ export interface IWebpackConfig {
389
370
  */
390
371
  export type WebpackEnvType = { [key: string]: any } | string;
391
372
 
392
- export interface IViolation {
393
- /**
394
- * The violated rule
395
- */
396
- rule: IRuleSummary;
397
- /**
398
- * The from part of the dependency this violation is about
399
- */
400
- from: string;
401
- /**
402
- * The to part of the dependency this violation is about
403
- */
404
- to: string;
405
- /**
406
- * The circular path if the violation is about circularity
407
- */
408
- cycle?: string[];
409
- /**
410
- * The path from the from to the to if the violation is transitive
411
- */
412
- via?: string[];
413
- }
414
-
415
373
  export interface IFolder {
416
374
  /**
417
375
  * The name of the folder. FOlder names are normalized to posix (so
@@ -421,11 +379,11 @@ export interface IFolder {
421
379
  /**
422
380
  * List of folders depending on this folder
423
381
  */
424
- dependents?: string[];
382
+ dependents?: { name: string }[];
425
383
  /**
426
384
  * List of folders this folder depends upon
427
385
  */
428
- dependencies?: string[];
386
+ dependencies?: { name: string; instability: number }[];
429
387
  /**
430
388
  * The total number of modules detected in this folder and its sub-folders
431
389
  */
@@ -455,3 +413,6 @@ export interface IFolder {
455
413
  */
456
414
  instability?: number;
457
415
  }
416
+
417
+ export * from "./violations";
418
+ export * from "./rule-summary";
@@ -239,4 +239,9 @@ export interface ICruiseOptions {
239
239
  */
240
240
  type: ProgressType;
241
241
  };
242
+ /**
243
+ * When this flag is set to true, dependency-cruiser will calculate (stability) metrics
244
+ * for all modules and folders. Defaults to false.
245
+ */
246
+ metrics?: boolean;
242
247
  }
@@ -58,6 +58,12 @@ export interface IDotReporterOptions {
58
58
  * goal of the report)
59
59
  */
60
60
  filters?: IReporterFiltersType;
61
+ /**
62
+ * When passed the value 'true', shows instability metrics in the
63
+ * output if dependency-cruiser calculated them. Doesn't show them
64
+ * in all other cases. Defaults to false",
65
+ */
66
+ showMetrics?: boolean;
61
67
  /**
62
68
  * A bunch of criteria to (conditionally) theme the dot output
63
69
  */
@@ -92,6 +92,18 @@ export interface IToRestriction extends IBaseRestrictionType {
92
92
  * licenses. E.g. to flag everyting non MIT use "MIT" here
93
93
  */
94
94
  licenseNot?: string | string[];
95
+ /**
96
+ * When set to true moreUnstable matches for any dependency that has a higher
97
+ * Instability than the module that depends on it. When set to false it matches
98
+ * when the opposite is true; the dependency has an equal or lower Instability.
99
+ *
100
+ * This attribute is useful when you want to check against Robert C. Martin's
101
+ * stable dependency * principle. See online documentation for examples and
102
+ * details.
103
+ *
104
+ * Leave this out when you don't care either way.
105
+ */
106
+ moreUnstable?: boolean;
95
107
  }
96
108
 
97
109
  export interface IReachabilityToRestrictionType extends IBaseRestrictionType {
@@ -0,0 +1,23 @@
1
+ import { SeverityType } from "./shared-types";
2
+
3
+ /**
4
+ * If there was a rule violation (valid === false), this object contains the name of the
5
+ * rule and severity of violating it.
6
+ */
7
+
8
+ export interface IRuleSummary {
9
+ /**
10
+ * The (short, eslint style) name of the violated rule. Typically something like
11
+ * 'no-core-punycode' or 'no-outside-deps'.
12
+ */
13
+ name: string;
14
+ /**
15
+ * How severe a violation of a rule is. The 'error' severity will make some reporters return
16
+ * a non-zero exit code, so if you want e.g. a build to stop when there's a rule violated:
17
+ * use that. The absence of the 'ignore' severity here is by design; ignored rules don't
18
+ * show up in the output.
19
+ *
20
+ * Severity to use when a dependency is not in the 'allowed' set of rules. Defaults to 'warn'
21
+ */
22
+ severity: SeverityType;
23
+ }
@@ -42,3 +42,10 @@ export type DependencyType =
42
42
  | "type-only";
43
43
 
44
44
  export type ProtocolType = "data:" | "file:" | "node:";
45
+
46
+ export type ViolationType =
47
+ | "dependency"
48
+ | "module"
49
+ | "cycle"
50
+ | "reachability"
51
+ | "instability";
@@ -0,0 +1,43 @@
1
+ import { IRuleSummary } from "./rule-summary";
2
+ import { ViolationType } from "./shared-types";
3
+
4
+ export interface IMetricsSummary {
5
+ from: {
6
+ instability: number;
7
+ };
8
+ to: {
9
+ instability: number;
10
+ };
11
+ }
12
+
13
+ export interface IViolation {
14
+ /**
15
+ * Type of violation. When left out assumed to be of type 'dependency'
16
+ */
17
+ type?: ViolationType;
18
+ /**
19
+ * The violated rule
20
+ */
21
+ rule: IRuleSummary;
22
+ /**
23
+ * The from part of the dependency this violation is about
24
+ */
25
+ from: string;
26
+ /**
27
+ * The to part of the dependency this violation is about
28
+ */
29
+ to: string;
30
+ /**
31
+ * The circular path if the violation is about circularity
32
+ */
33
+ cycle?: string[];
34
+ /**
35
+ * The path from the from to the to if the violation is transitive
36
+ */
37
+ via?: string[];
38
+ /**
39
+ * metrics - when the violation pertains to a violation of a metrics
40
+ * principle
41
+ */
42
+ metrics?: IMetricsSummary;
43
+ }
@@ -1,9 +0,0 @@
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
- };
@@ -1,27 +0,0 @@
1
- const path = require("path").posix;
2
-
3
- function getAfferentCouplings(pModule, pDirname) {
4
- return pModule.dependents.filter(
5
- (pDependent) => !pDependent.startsWith(pDirname.concat(path.sep))
6
- );
7
- }
8
-
9
- function getEfferentCouplings(pModule, pDirname) {
10
- return pModule.dependencies.filter(
11
- (pDependency) => !pDependency.resolved.startsWith(pDirname.concat(path.sep))
12
- );
13
- }
14
-
15
- function metricsAreCalculable(pModule) {
16
- return (
17
- !pModule.coreModule &&
18
- !pModule.couldNotResolve &&
19
- !pModule.matchesDoNotFollow
20
- );
21
- }
22
-
23
- module.exports = {
24
- getAfferentCouplings,
25
- getEfferentCouplings,
26
- metricsAreCalculable,
27
- };
@@ -1,29 +0,0 @@
1
- // const { findModuleByName, clearCache } = require("../utl");
2
- const { metricsAreCalculable } = require("./module-utl");
3
- const { shouldDeriveMetrics } = require("./utl");
4
-
5
- module.exports = function deriveModuleMetrics(pModules, pOptions) {
6
- if (shouldDeriveMetrics(pOptions)) {
7
- return pModules.map((pModule) => ({
8
- ...pModule,
9
- ...(metricsAreCalculable(pModule)
10
- ? {
11
- instability:
12
- pModule.dependencies.length /
13
- (pModule.dependents.length + pModule.dependencies.length) || 0,
14
- }
15
- : {}),
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
- // }));
27
- }
28
- return pModules;
29
- };
@@ -1,28 +0,0 @@
1
- /* eslint-disable security/detect-object-injection */
2
- function getParentFolders(pPath) {
3
- let lFragments = pPath.split("/");
4
- let lReturnValue = [];
5
-
6
- while (lFragments.length > 0) {
7
- lReturnValue.push(lFragments.join("/"));
8
- lFragments.pop();
9
- }
10
- return lReturnValue.reverse();
11
- }
12
-
13
- function foldersObject2folderArray(pObject) {
14
- return Object.keys(pObject).map((pKey) => ({
15
- name: pKey,
16
- ...pObject[pKey],
17
- }));
18
- }
19
-
20
- function shouldDeriveMetrics(pOptions) {
21
- return pOptions.metrics || pOptions.outputType === "metrics";
22
- }
23
-
24
- module.exports = {
25
- getParentFolders,
26
- foldersObject2folderArray,
27
- shouldDeriveMetrics,
28
- };
@@ -1,31 +0,0 @@
1
- /**
2
- * If there is at least one group expression in the given pRulePath
3
- * return the first matched one.
4
- *
5
- * Return null in all other cases.
6
- *
7
- * This fills our current need. Later we can expand it to return all group
8
- * matches.
9
- *
10
- * @param {import("../../types/rule-set").IFromRestriction} pRestriction
11
- * @param {string} pActualPath
12
- * @returns {string[]|null}
13
- */
14
- function extractGroups(pRestriction, pActualPath) {
15
- let lReturnValue = [];
16
-
17
- if (Boolean(pRestriction.path)) {
18
- let lMatchResult = pActualPath.match(pRestriction.path);
19
-
20
- if (Boolean(lMatchResult) && lMatchResult.length > 1) {
21
- lReturnValue = lMatchResult.filter(
22
- (pResult) => typeof pResult === "string"
23
- );
24
- }
25
- }
26
- return lReturnValue;
27
- }
28
-
29
- module.exports = {
30
- extractGroups,
31
- };