@skastr0/pulsar-rs-pack 0.1.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.
- package/dist/cargo-metadata.d.ts +59 -0
- package/dist/cargo-metadata.d.ts.map +1 -0
- package/dist/cargo-metadata.js +162 -0
- package/dist/cargo-metadata.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/lock-file.d.ts +20 -0
- package/dist/lock-file.d.ts.map +1 -0
- package/dist/lock-file.js +144 -0
- package/dist/lock-file.js.map +1 -0
- package/dist/pack.d.ts +6 -0
- package/dist/pack.d.ts.map +1 -0
- package/dist/pack.js +55 -0
- package/dist/pack.js.map +1 -0
- package/dist/project.d.ts +26 -0
- package/dist/project.d.ts.map +1 -0
- package/dist/project.js +172 -0
- package/dist/project.js.map +1 -0
- package/dist/rust-analysis-collect.d.ts +4 -0
- package/dist/rust-analysis-collect.d.ts.map +1 -0
- package/dist/rust-analysis-collect.js +84 -0
- package/dist/rust-analysis-collect.js.map +1 -0
- package/dist/rust-analysis-functions.d.ts +4 -0
- package/dist/rust-analysis-functions.d.ts.map +1 -0
- package/dist/rust-analysis-functions.js +140 -0
- package/dist/rust-analysis-functions.js.map +1 -0
- package/dist/rust-analysis-identifiers.d.ts +3 -0
- package/dist/rust-analysis-identifiers.d.ts.map +1 -0
- package/dist/rust-analysis-identifiers.js +5 -0
- package/dist/rust-analysis-identifiers.js.map +1 -0
- package/dist/rust-analysis-items.d.ts +4 -0
- package/dist/rust-analysis-items.d.ts.map +1 -0
- package/dist/rust-analysis-items.js +58 -0
- package/dist/rust-analysis-items.js.map +1 -0
- package/dist/rust-analysis-modules.d.ts +7 -0
- package/dist/rust-analysis-modules.d.ts.map +1 -0
- package/dist/rust-analysis-modules.js +52 -0
- package/dist/rust-analysis-modules.js.map +1 -0
- package/dist/rust-analysis-syntax.d.ts +12 -0
- package/dist/rust-analysis-syntax.d.ts.map +1 -0
- package/dist/rust-analysis-syntax.js +102 -0
- package/dist/rust-analysis-syntax.js.map +1 -0
- package/dist/rust-analysis-types.d.ts +109 -0
- package/dist/rust-analysis-types.d.ts.map +1 -0
- package/dist/rust-analysis-types.js +2 -0
- package/dist/rust-analysis-types.js.map +1 -0
- package/dist/rust-analysis-uses.d.ts +4 -0
- package/dist/rust-analysis-uses.d.ts.map +1 -0
- package/dist/rust-analysis-uses.js +63 -0
- package/dist/rust-analysis-uses.js.map +1 -0
- package/dist/rust-analysis.d.ts +5 -0
- package/dist/rust-analysis.d.ts.map +1 -0
- package/dist/rust-analysis.js +4 -0
- package/dist/rust-analysis.js.map +1 -0
- package/dist/signals/rs-ab-01-unused-pub.d.ts +29 -0
- package/dist/signals/rs-ab-01-unused-pub.d.ts.map +1 -0
- package/dist/signals/rs-ab-01-unused-pub.js +184 -0
- package/dist/signals/rs-ab-01-unused-pub.js.map +1 -0
- package/dist/signals/rs-ab-02-trait-object-depth.d.ts +26 -0
- package/dist/signals/rs-ab-02-trait-object-depth.d.ts.map +1 -0
- package/dist/signals/rs-ab-02-trait-object-depth.js +157 -0
- package/dist/signals/rs-ab-02-trait-object-depth.js.map +1 -0
- package/dist/signals/rs-ab-03-generic-proliferation.d.ts +28 -0
- package/dist/signals/rs-ab-03-generic-proliferation.d.ts.map +1 -0
- package/dist/signals/rs-ab-03-generic-proliferation.js +108 -0
- package/dist/signals/rs-ab-03-generic-proliferation.js.map +1 -0
- package/dist/signals/rs-ab-04-derive-density.d.ts +25 -0
- package/dist/signals/rs-ab-04-derive-density.d.ts.map +1 -0
- package/dist/signals/rs-ab-04-derive-density.js +101 -0
- package/dist/signals/rs-ab-04-derive-density.js.map +1 -0
- package/dist/signals/rs-ad-01-visibility-surface.d.ts +29 -0
- package/dist/signals/rs-ad-01-visibility-surface.d.ts.map +1 -0
- package/dist/signals/rs-ad-01-visibility-surface.js +129 -0
- package/dist/signals/rs-ad-01-visibility-surface.js.map +1 -0
- package/dist/signals/rs-ad-02-boundary-rules.d.ts +3 -0
- package/dist/signals/rs-ad-02-boundary-rules.d.ts.map +1 -0
- package/dist/signals/rs-ad-02-boundary-rules.js +26 -0
- package/dist/signals/rs-ad-02-boundary-rules.js.map +1 -0
- package/dist/signals/rs-ad-02-crate-analysis.d.ts +9 -0
- package/dist/signals/rs-ad-02-crate-analysis.d.ts.map +1 -0
- package/dist/signals/rs-ad-02-crate-analysis.js +117 -0
- package/dist/signals/rs-ad-02-crate-analysis.js.map +1 -0
- package/dist/signals/rs-ad-02-crate-boundaries.d.ts +6 -0
- package/dist/signals/rs-ad-02-crate-boundaries.d.ts.map +1 -0
- package/dist/signals/rs-ad-02-crate-boundaries.js +84 -0
- package/dist/signals/rs-ad-02-crate-boundaries.js.map +1 -0
- package/dist/signals/rs-ad-02-types.d.ts +26 -0
- package/dist/signals/rs-ad-02-types.d.ts.map +1 -0
- package/dist/signals/rs-ad-02-types.js +6 -0
- package/dist/signals/rs-ad-02-types.js.map +1 -0
- package/dist/signals/rs-ad-03-circular-crate-deps.d.ts +30 -0
- package/dist/signals/rs-ad-03-circular-crate-deps.d.ts.map +1 -0
- package/dist/signals/rs-ad-03-circular-crate-deps.js +185 -0
- package/dist/signals/rs-ad-03-circular-crate-deps.js.map +1 -0
- package/dist/signals/rs-de-01-trait-coupling.d.ts +43 -0
- package/dist/signals/rs-de-01-trait-coupling.d.ts.map +1 -0
- package/dist/signals/rs-de-01-trait-coupling.js +222 -0
- package/dist/signals/rs-de-01-trait-coupling.js.map +1 -0
- package/dist/signals/rs-de-02-dep-tree.d.ts +28 -0
- package/dist/signals/rs-de-02-dep-tree.d.ts.map +1 -0
- package/dist/signals/rs-de-02-dep-tree.js +173 -0
- package/dist/signals/rs-de-02-dep-tree.js.map +1 -0
- package/dist/signals/rs-de-03-feature-flags.d.ts +32 -0
- package/dist/signals/rs-de-03-feature-flags.d.ts.map +1 -0
- package/dist/signals/rs-de-03-feature-flags.js +139 -0
- package/dist/signals/rs-de-03-feature-flags.js.map +1 -0
- package/dist/signals/rs-de-04-fan-in-fan-out.d.ts +28 -0
- package/dist/signals/rs-de-04-fan-in-fan-out.d.ts.map +1 -0
- package/dist/signals/rs-de-04-fan-in-fan-out.js +109 -0
- package/dist/signals/rs-de-04-fan-in-fan-out.js.map +1 -0
- package/dist/signals/rs-ld-01-unsafe.d.ts +28 -0
- package/dist/signals/rs-ld-01-unsafe.d.ts.map +1 -0
- package/dist/signals/rs-ld-01-unsafe.js +116 -0
- package/dist/signals/rs-ld-01-unsafe.js.map +1 -0
- package/dist/signals/rs-ld-02-lifetimes.d.ts +30 -0
- package/dist/signals/rs-ld-02-lifetimes.d.ts.map +1 -0
- package/dist/signals/rs-ld-02-lifetimes.js +79 -0
- package/dist/signals/rs-ld-02-lifetimes.js.map +1 -0
- package/dist/signals/rs-ld-03-match-catch-all.d.ts +26 -0
- package/dist/signals/rs-ld-03-match-catch-all.d.ts.map +1 -0
- package/dist/signals/rs-ld-03-match-catch-all.js +68 -0
- package/dist/signals/rs-ld-03-match-catch-all.js.map +1 -0
- package/dist/signals/rs-ld-04-error-granularity.d.ts +25 -0
- package/dist/signals/rs-ld-04-error-granularity.d.ts.map +1 -0
- package/dist/signals/rs-ld-04-error-granularity.js +77 -0
- package/dist/signals/rs-ld-04-error-granularity.js.map +1 -0
- package/dist/signals/rs-ld-05-complexity.d.ts +26 -0
- package/dist/signals/rs-ld-05-complexity.d.ts.map +1 -0
- package/dist/signals/rs-ld-05-complexity.js +70 -0
- package/dist/signals/rs-ld-05-complexity.js.map +1 -0
- package/dist/signals/rs-ld-06-domain-terms.d.ts +29 -0
- package/dist/signals/rs-ld-06-domain-terms.d.ts.map +1 -0
- package/dist/signals/rs-ld-06-domain-terms.js +158 -0
- package/dist/signals/rs-ld-06-domain-terms.js.map +1 -0
- package/dist/signals/rs-rp-01-hotspots.d.ts +27 -0
- package/dist/signals/rs-rp-01-hotspots.d.ts.map +1 -0
- package/dist/signals/rs-rp-01-hotspots.js +110 -0
- package/dist/signals/rs-rp-01-hotspots.js.map +1 -0
- package/dist/signals/rs-rp-02-compile-time.d.ts +25 -0
- package/dist/signals/rs-rp-02-compile-time.d.ts.map +1 -0
- package/dist/signals/rs-rp-02-compile-time.js +177 -0
- package/dist/signals/rs-rp-02-compile-time.js.map +1 -0
- package/dist/signals/rs-rp-03-pr-size.d.ts +23 -0
- package/dist/signals/rs-rp-03-pr-size.d.ts.map +1 -0
- package/dist/signals/rs-rp-03-pr-size.js +160 -0
- package/dist/signals/rs-rp-03-pr-size.js.map +1 -0
- package/dist/signals/rs-sl-01-duplication.d.ts +28 -0
- package/dist/signals/rs-sl-01-duplication.d.ts.map +1 -0
- package/dist/signals/rs-sl-01-duplication.js +172 -0
- package/dist/signals/rs-sl-01-duplication.js.map +1 -0
- package/dist/signals/rs-sl-02-suppressions.d.ts +30 -0
- package/dist/signals/rs-sl-02-suppressions.d.ts.map +1 -0
- package/dist/signals/rs-sl-02-suppressions.js +176 -0
- package/dist/signals/rs-sl-02-suppressions.js.map +1 -0
- package/dist/signals/rs-sl-03-unwrap-expect.d.ts +22 -0
- package/dist/signals/rs-sl-03-unwrap-expect.d.ts.map +1 -0
- package/dist/signals/rs-sl-03-unwrap-expect.js +94 -0
- package/dist/signals/rs-sl-03-unwrap-expect.js.map +1 -0
- package/dist/signals/rs-sl-04-clone-abuse.d.ts +22 -0
- package/dist/signals/rs-sl-04-clone-abuse.d.ts.map +1 -0
- package/dist/signals/rs-sl-04-clone-abuse.js +115 -0
- package/dist/signals/rs-sl-04-clone-abuse.js.map +1 -0
- package/dist/signals/shared-globs.d.ts +4 -0
- package/dist/signals/shared-globs.d.ts.map +1 -0
- package/dist/signals/shared-globs.js +12 -0
- package/dist/signals/shared-globs.js.map +1 -0
- package/dist/signals/shared-record-guards.d.ts +4 -0
- package/dist/signals/shared-record-guards.d.ts.map +1 -0
- package/dist/signals/shared-record-guards.js +4 -0
- package/dist/signals/shared-record-guards.js.map +1 -0
- package/dist/signals/shared-rust-ast.d.ts +30 -0
- package/dist/signals/shared-rust-ast.d.ts.map +1 -0
- package/dist/signals/shared-rust-ast.js +78 -0
- package/dist/signals/shared-rust-ast.js.map +1 -0
- package/dist/signals/shared-rust-resolution.d.ts +10 -0
- package/dist/signals/shared-rust-resolution.d.ts.map +1 -0
- package/dist/signals/shared-rust-resolution.js +53 -0
- package/dist/signals/shared-rust-resolution.js.map +1 -0
- package/dist/signals/shared-threshold-score.d.ts +2 -0
- package/dist/signals/shared-threshold-score.d.ts.map +1 -0
- package/dist/signals/shared-threshold-score.js +6 -0
- package/dist/signals/shared-threshold-score.js.map +1 -0
- package/dist/syn-walker.d.ts +7 -0
- package/dist/syn-walker.d.ts.map +1 -0
- package/dist/syn-walker.js +61 -0
- package/dist/syn-walker.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { SignalComputeError, } from "@skastr0/pulsar-core/signal";
|
|
2
|
+
import { Effect, Schema } from "effect";
|
|
3
|
+
import { collectRustProjectFacts } from "../rust-analysis.js";
|
|
4
|
+
import { RustProjectTag } from "../project.js";
|
|
5
|
+
import { parseRustFile } from "../syn-walker.js";
|
|
6
|
+
import { DEFAULT_RUST_EXCLUDE_GLOBS, firstNamedChild, modulePathForAncestors, namedChildrenOf, resolveRustFileScope, walkAttributedNodes, } from "./shared-rust-ast.js";
|
|
7
|
+
import { isExcluded } from "./shared-globs.js";
|
|
8
|
+
const RsDe01Config = Schema.Struct({
|
|
9
|
+
exclude_globs: Schema.Array(Schema.String),
|
|
10
|
+
top_n_diagnostics: Schema.Number,
|
|
11
|
+
});
|
|
12
|
+
export const RsDe01 = {
|
|
13
|
+
id: "RS-DE-01-trait-coupling",
|
|
14
|
+
title: "Trait coupling",
|
|
15
|
+
aliases: ["RS-DE-01"],
|
|
16
|
+
tier: 1,
|
|
17
|
+
category: "dependency-entropy",
|
|
18
|
+
kind: "structural",
|
|
19
|
+
configSchema: RsDe01Config,
|
|
20
|
+
defaultConfig: {
|
|
21
|
+
exclude_globs: [...DEFAULT_RUST_EXCLUDE_GLOBS],
|
|
22
|
+
top_n_diagnostics: 10,
|
|
23
|
+
},
|
|
24
|
+
inputs: [],
|
|
25
|
+
compute: (config) => Effect.gen(function* () {
|
|
26
|
+
const project = yield* RustProjectTag;
|
|
27
|
+
return yield* Effect.tryPromise({
|
|
28
|
+
try: async () => {
|
|
29
|
+
const facts = await collectRustProjectFacts(project);
|
|
30
|
+
const localTraitNames = new Map();
|
|
31
|
+
const localTypeNames = new Map();
|
|
32
|
+
const crateRootNames = new Map();
|
|
33
|
+
for (const item of facts.items) {
|
|
34
|
+
const traitBucket = localTraitNames.get(item.crateName) ?? new Set();
|
|
35
|
+
const typeBucket = localTypeNames.get(item.crateName) ?? new Set();
|
|
36
|
+
const rootBucket = crateRootNames.get(item.crateName) ?? new Set();
|
|
37
|
+
if (item.kind === "trait")
|
|
38
|
+
traitBucket.add(item.name);
|
|
39
|
+
if (["struct", "enum", "type"].includes(item.kind))
|
|
40
|
+
typeBucket.add(item.name);
|
|
41
|
+
if (item.relativeModulePath === "crate")
|
|
42
|
+
rootBucket.add(item.name);
|
|
43
|
+
localTraitNames.set(item.crateName, traitBucket);
|
|
44
|
+
localTypeNames.set(item.crateName, typeBucket);
|
|
45
|
+
crateRootNames.set(item.crateName, rootBucket);
|
|
46
|
+
}
|
|
47
|
+
for (const module of facts.modules) {
|
|
48
|
+
const rootBucket = crateRootNames.get(module.crateName) ?? new Set();
|
|
49
|
+
const segments = module.relativeModulePath.split("::");
|
|
50
|
+
const root = segments[1];
|
|
51
|
+
if (segments[0] === "crate" && root !== undefined)
|
|
52
|
+
rootBucket.add(root);
|
|
53
|
+
crateRootNames.set(module.crateName, rootBucket);
|
|
54
|
+
}
|
|
55
|
+
const grouped = new Map();
|
|
56
|
+
for (const file of project.sourceFiles) {
|
|
57
|
+
if (isExcluded(file, config.exclude_globs))
|
|
58
|
+
continue;
|
|
59
|
+
const scope = resolveRustFileScope(project, file);
|
|
60
|
+
const tree = await parseRustFile(file);
|
|
61
|
+
walkAttributedNodes(tree.rootNode, ({ node, ancestors }) => {
|
|
62
|
+
if (node.type !== "impl_item")
|
|
63
|
+
return;
|
|
64
|
+
const filteredChildren = namedChildrenOf(node).filter((child) => child.type !== "type_parameters" &&
|
|
65
|
+
child.type !== "where_clause" &&
|
|
66
|
+
child.type !== "declaration_list");
|
|
67
|
+
if (filteredChildren.length < 2)
|
|
68
|
+
return;
|
|
69
|
+
const traitNode = filteredChildren[0];
|
|
70
|
+
const typeNode = filteredChildren[1];
|
|
71
|
+
if (traitNode === undefined || typeNode === undefined)
|
|
72
|
+
return;
|
|
73
|
+
const traitLocal = isLocalPath(traitNode, scope.crateName, localTraitNames.get(scope.crateName) ?? new Set(), crateRootNames.get(scope.crateName) ?? new Set());
|
|
74
|
+
if (traitLocal)
|
|
75
|
+
return;
|
|
76
|
+
const typeLocal = isLocalPath(typeNode, scope.crateName, localTypeNames.get(scope.crateName) ?? new Set(), crateRootNames.get(scope.crateName) ?? new Set());
|
|
77
|
+
const { modulePath } = modulePathForAncestors(scope, ancestors);
|
|
78
|
+
const family = classifyForeignTrait(traitNode.text);
|
|
79
|
+
const detail = {
|
|
80
|
+
trait: traitNode.text,
|
|
81
|
+
type: typeNode.text,
|
|
82
|
+
file,
|
|
83
|
+
line: node.startPosition.row + 1,
|
|
84
|
+
traitLocal,
|
|
85
|
+
typeLocal,
|
|
86
|
+
orphanWorkaroundCandidate: !traitLocal && !typeLocal,
|
|
87
|
+
family,
|
|
88
|
+
concerning: family === "application-external" || (!traitLocal && !typeLocal),
|
|
89
|
+
};
|
|
90
|
+
const current = grouped.get(modulePath);
|
|
91
|
+
const nextDetails = [...(current?.details ?? []), detail].sort((left, right) => left.line - right.line);
|
|
92
|
+
grouped.set(modulePath, {
|
|
93
|
+
module: modulePath,
|
|
94
|
+
file,
|
|
95
|
+
foreignTraitImpls: nextDetails.length,
|
|
96
|
+
concerningForeignTraitImpls: nextDetails.filter((entry) => entry.concerning).length,
|
|
97
|
+
ordinaryForeignTraitImpls: nextDetails.filter((entry) => !entry.concerning).length,
|
|
98
|
+
details: nextDetails,
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
const modules = [...grouped.values()].sort((left, right) => right.concerningForeignTraitImpls - left.concerningForeignTraitImpls ||
|
|
103
|
+
right.foreignTraitImpls - left.foreignTraitImpls ||
|
|
104
|
+
left.module.localeCompare(right.module));
|
|
105
|
+
return {
|
|
106
|
+
byModule: new Map(modules.map((module) => [
|
|
107
|
+
module.module,
|
|
108
|
+
{
|
|
109
|
+
foreignTraitImpls: module.foreignTraitImpls,
|
|
110
|
+
concerningForeignTraitImpls: module.concerningForeignTraitImpls,
|
|
111
|
+
ordinaryForeignTraitImpls: module.ordinaryForeignTraitImpls,
|
|
112
|
+
details: module.details,
|
|
113
|
+
},
|
|
114
|
+
])),
|
|
115
|
+
modules,
|
|
116
|
+
totalForeignTraitImpls: modules.reduce((sum, module) => sum + module.foreignTraitImpls, 0),
|
|
117
|
+
totalConcerningForeignTraitImpls: modules.reduce((sum, module) => sum + module.concerningForeignTraitImpls, 0),
|
|
118
|
+
analysisMode: "syntax-and-local-name-resolution",
|
|
119
|
+
};
|
|
120
|
+
},
|
|
121
|
+
catch: (cause) => new SignalComputeError({ signalId: "RS-DE-01-trait-coupling", message: String(cause), cause }),
|
|
122
|
+
});
|
|
123
|
+
}),
|
|
124
|
+
score: (out) => {
|
|
125
|
+
if (out.modules.length === 0)
|
|
126
|
+
return 1;
|
|
127
|
+
const average = out.totalConcerningForeignTraitImpls / out.modules.length;
|
|
128
|
+
return Math.max(0, 1 - Math.min(1, average / 2));
|
|
129
|
+
},
|
|
130
|
+
diagnose: (out) => out.modules.filter((module) => module.concerningForeignTraitImpls > 0).slice(0, 10).map((module) => ({
|
|
131
|
+
severity: module.details.some((detail) => detail.concerning && detail.orphanWorkaroundCandidate)
|
|
132
|
+
? "warn"
|
|
133
|
+
: "info",
|
|
134
|
+
message: `Module ${module.module} implements ${module.concerningForeignTraitImpls} concerning foreign traits (${module.ordinaryForeignTraitImpls} ordinary)`,
|
|
135
|
+
location: { file: module.file },
|
|
136
|
+
data: {
|
|
137
|
+
module: module.module,
|
|
138
|
+
foreignTraitImpls: module.foreignTraitImpls,
|
|
139
|
+
concerningForeignTraitImpls: module.concerningForeignTraitImpls,
|
|
140
|
+
ordinaryForeignTraitImpls: module.ordinaryForeignTraitImpls,
|
|
141
|
+
orphanWorkaroundCandidates: module.details.filter((detail) => detail.concerning && detail.orphanWorkaroundCandidate).length,
|
|
142
|
+
analysisMode: out.analysisMode,
|
|
143
|
+
},
|
|
144
|
+
})),
|
|
145
|
+
};
|
|
146
|
+
const STANDARD_ERGONOMIC_TRAITS = new Set([
|
|
147
|
+
"AsMut",
|
|
148
|
+
"AsRef",
|
|
149
|
+
"Clone",
|
|
150
|
+
"Copy",
|
|
151
|
+
"Debug",
|
|
152
|
+
"Default",
|
|
153
|
+
"Deref",
|
|
154
|
+
"DerefMut",
|
|
155
|
+
"Display",
|
|
156
|
+
"Drop",
|
|
157
|
+
"Eq",
|
|
158
|
+
"Error",
|
|
159
|
+
"Extend",
|
|
160
|
+
"From",
|
|
161
|
+
"FromIterator",
|
|
162
|
+
"FromStr",
|
|
163
|
+
"Hash",
|
|
164
|
+
"Index",
|
|
165
|
+
"IndexMut",
|
|
166
|
+
"Into",
|
|
167
|
+
"IntoIterator",
|
|
168
|
+
"Iterator",
|
|
169
|
+
"Ord",
|
|
170
|
+
"PartialEq",
|
|
171
|
+
"PartialOrd",
|
|
172
|
+
"ToString",
|
|
173
|
+
"TryFrom",
|
|
174
|
+
"TryInto",
|
|
175
|
+
]);
|
|
176
|
+
const SERIALIZATION_TRAITS = new Set(["Deserialize", "Serialize"]);
|
|
177
|
+
const FRAMEWORK_ADAPTER_TRAITS = new Set(["IntoResponse"]);
|
|
178
|
+
const classifyForeignTrait = (traitName) => {
|
|
179
|
+
const segment = finalTraitSegment(traitName);
|
|
180
|
+
if (STANDARD_ERGONOMIC_TRAITS.has(segment))
|
|
181
|
+
return "standard-library-ergonomic";
|
|
182
|
+
if (SERIALIZATION_TRAITS.has(segment))
|
|
183
|
+
return "serialization";
|
|
184
|
+
if (FRAMEWORK_ADAPTER_TRAITS.has(segment))
|
|
185
|
+
return "framework-adapter";
|
|
186
|
+
return "application-external";
|
|
187
|
+
};
|
|
188
|
+
const finalTraitSegment = (traitName) => {
|
|
189
|
+
const withoutGenerics = traitName.replace(/<.*$/, "");
|
|
190
|
+
return withoutGenerics.split("::").at(-1)?.trim() ?? withoutGenerics.trim();
|
|
191
|
+
};
|
|
192
|
+
const isLocalPath = (node, crateName, localNames, crateRootNames) => {
|
|
193
|
+
const root = symbolRoot(node);
|
|
194
|
+
if (root === undefined)
|
|
195
|
+
return false;
|
|
196
|
+
if (["crate", "self", "super", crateName].includes(root))
|
|
197
|
+
return true;
|
|
198
|
+
return localNames.has(root) || crateRootNames.has(root);
|
|
199
|
+
};
|
|
200
|
+
const symbolRoot = (node) => {
|
|
201
|
+
switch (node.type) {
|
|
202
|
+
case "identifier":
|
|
203
|
+
case "type_identifier":
|
|
204
|
+
case "primitive_type":
|
|
205
|
+
case "crate":
|
|
206
|
+
case "self":
|
|
207
|
+
case "super":
|
|
208
|
+
return node.text;
|
|
209
|
+
case "scoped_identifier":
|
|
210
|
+
case "scoped_type_identifier":
|
|
211
|
+
return namedChildrenOf(node)[0]?.text;
|
|
212
|
+
case "generic_type":
|
|
213
|
+
case "reference_type":
|
|
214
|
+
case "pointer_type":
|
|
215
|
+
case "dynamic_type":
|
|
216
|
+
case "bounded_type":
|
|
217
|
+
return symbolRoot(namedChildrenOf(node)[0] ?? node);
|
|
218
|
+
default:
|
|
219
|
+
return firstNamedChild(node, "type_identifier")?.text ?? firstNamedChild(node, "identifier")?.text;
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
//# sourceMappingURL=rs-de-01-trait-coupling.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rs-de-01-trait-coupling.js","sourceRoot":"","sources":["../../src/signals/rs-de-01-trait-coupling.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Signal } from "@skastr0/pulsar-core/signal";
|
|
2
|
+
import { Schema } from "effect";
|
|
3
|
+
import { RustProjectTag } from "../project.js";
|
|
4
|
+
declare const RsDe02Config: Schema.Struct<{
|
|
5
|
+
top_n_diagnostics: typeof Schema.Number;
|
|
6
|
+
}>;
|
|
7
|
+
type RsDe02Config = typeof RsDe02Config.Type;
|
|
8
|
+
interface DependencyDuplicateGroup {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly versions: ReadonlyArray<string>;
|
|
11
|
+
readonly instanceCount: number;
|
|
12
|
+
}
|
|
13
|
+
interface TopLevelDependencyDepth {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly rootInstances: number;
|
|
16
|
+
readonly maxDepth: number;
|
|
17
|
+
readonly reachablePackages: number;
|
|
18
|
+
}
|
|
19
|
+
interface RsDe02Output {
|
|
20
|
+
readonly duplicates: ReadonlyArray<DependencyDuplicateGroup>;
|
|
21
|
+
readonly topLevelDependencies: ReadonlyArray<TopLevelDependencyDepth>;
|
|
22
|
+
readonly duplicateCount: number;
|
|
23
|
+
readonly lockfileStatus: "loaded" | "missing";
|
|
24
|
+
readonly analysisMode: "cargo-lock";
|
|
25
|
+
}
|
|
26
|
+
export declare const RsDe02: Signal<RsDe02Config, RsDe02Output, RustProjectTag>;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=rs-de-02-dep-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rs-de-02-dep-tree.d.ts","sourceRoot":"","sources":["../../src/signals/rs-de-02-dep-tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,MAAM,EAEZ,MAAM,6BAA6B,CAAA;AAEpC,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAA;AAKvC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAE9C,QAAA,MAAM,YAAY;;EAEhB,CAAA;AACF,KAAK,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAE5C,UAAU,wBAAwB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACxC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAC/B;AAED,UAAU,uBAAuB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;CACnC;AAED,UAAU,YAAY;IACpB,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,wBAAwB,CAAC,CAAA;IAC5D,QAAQ,CAAC,oBAAoB,EAAE,aAAa,CAAC,uBAAuB,CAAC,CAAA;IACrE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,cAAc,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC7C,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAA;CACpC;AAED,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,YAAY,EAAE,cAAc,CA8GrE,CAAA"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { SignalComputeError, } from "@skastr0/pulsar-core/signal";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { Effect, Schema } from "effect";
|
|
4
|
+
import { findDuplicateCargoLockPackages, } from "../lock-file.js";
|
|
5
|
+
import { RustProjectTag } from "../project.js";
|
|
6
|
+
const RsDe02Config = Schema.Struct({
|
|
7
|
+
top_n_diagnostics: Schema.Number,
|
|
8
|
+
});
|
|
9
|
+
export const RsDe02 = {
|
|
10
|
+
id: "RS-DE-02-dependency-tree",
|
|
11
|
+
title: "Dependency tree",
|
|
12
|
+
aliases: ["RS-DE-02"],
|
|
13
|
+
tier: 1,
|
|
14
|
+
category: "dependency-entropy",
|
|
15
|
+
kind: "structural",
|
|
16
|
+
configSchema: RsDe02Config,
|
|
17
|
+
defaultConfig: {
|
|
18
|
+
top_n_diagnostics: 10,
|
|
19
|
+
},
|
|
20
|
+
inputs: [],
|
|
21
|
+
compute: () => Effect.gen(function* () {
|
|
22
|
+
const project = yield* RustProjectTag;
|
|
23
|
+
return yield* Effect.tryPromise({
|
|
24
|
+
try: async () => {
|
|
25
|
+
if (project.cargoLock === undefined) {
|
|
26
|
+
return {
|
|
27
|
+
duplicates: [],
|
|
28
|
+
topLevelDependencies: [],
|
|
29
|
+
duplicateCount: 0,
|
|
30
|
+
lockfileStatus: "missing",
|
|
31
|
+
analysisMode: "cargo-lock",
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const topLevelNames = new Set();
|
|
35
|
+
for (const manifest of project.manifests) {
|
|
36
|
+
for (const dependencyName of await parseManifestDependencyNames(manifest.manifestPath)) {
|
|
37
|
+
topLevelNames.add(dependencyName);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const workspacePackages = new Set(project.manifests
|
|
41
|
+
.map((manifest) => manifest.packageName)
|
|
42
|
+
.filter((name) => name !== undefined));
|
|
43
|
+
for (const workspacePackage of workspacePackages) {
|
|
44
|
+
topLevelNames.delete(workspacePackage);
|
|
45
|
+
}
|
|
46
|
+
const packageByKey = new Map(project.cargoLock.packages.map((pkg) => [packageKey(pkg.name, pkg.version), pkg]));
|
|
47
|
+
const packagesByName = new Map();
|
|
48
|
+
for (const pkg of project.cargoLock.packages) {
|
|
49
|
+
const bucket = packagesByName.get(pkg.name) ?? [];
|
|
50
|
+
bucket.push(pkg);
|
|
51
|
+
packagesByName.set(pkg.name, bucket);
|
|
52
|
+
}
|
|
53
|
+
const topLevelDependencies = [...topLevelNames]
|
|
54
|
+
.map((name) => describeTopLevelDependency(name, packagesByName, packageByKey))
|
|
55
|
+
.filter((entry) => entry !== undefined)
|
|
56
|
+
.sort((left, right) => right.maxDepth - left.maxDepth || left.name.localeCompare(right.name));
|
|
57
|
+
const duplicates = findDuplicateCargoLockPackages(project.cargoLock).map((group) => ({
|
|
58
|
+
name: group.name,
|
|
59
|
+
versions: group.versions,
|
|
60
|
+
instanceCount: group.packages.length,
|
|
61
|
+
}));
|
|
62
|
+
return {
|
|
63
|
+
duplicates,
|
|
64
|
+
topLevelDependencies,
|
|
65
|
+
duplicateCount: duplicates.length,
|
|
66
|
+
lockfileStatus: "loaded",
|
|
67
|
+
analysisMode: "cargo-lock",
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
catch: (cause) => new SignalComputeError({ signalId: "RS-DE-02-dependency-tree", message: String(cause), cause }),
|
|
71
|
+
});
|
|
72
|
+
}),
|
|
73
|
+
score: (out) => {
|
|
74
|
+
if (out.lockfileStatus === "missing")
|
|
75
|
+
return 1;
|
|
76
|
+
const depthPenalty = Math.min(0.5, out.topLevelDependencies.reduce((max, entry) => Math.max(max, entry.maxDepth), 0) / 20);
|
|
77
|
+
const duplicatePenalty = Math.min(0.5, out.duplicateCount / 10);
|
|
78
|
+
return Math.max(0, 1 - depthPenalty - duplicatePenalty);
|
|
79
|
+
},
|
|
80
|
+
diagnose: (out) => {
|
|
81
|
+
if (out.lockfileStatus === "missing") {
|
|
82
|
+
return [{ severity: "warn", message: "RS-DE-02 could not find Cargo.lock for dependency analysis" }];
|
|
83
|
+
}
|
|
84
|
+
const duplicateDiagnostics = out.duplicates.map((group) => ({
|
|
85
|
+
severity: "warn",
|
|
86
|
+
message: `Duplicate crate versions for ${group.name}: ${group.versions.join(", ")}`,
|
|
87
|
+
data: {
|
|
88
|
+
name: group.name,
|
|
89
|
+
versions: group.versions,
|
|
90
|
+
instanceCount: group.instanceCount,
|
|
91
|
+
},
|
|
92
|
+
}));
|
|
93
|
+
const depthDiagnostics = out.topLevelDependencies.slice(0, 5).map((entry) => ({
|
|
94
|
+
severity: entry.maxDepth >= 5 ? "warn" : "info",
|
|
95
|
+
message: `Top-level dependency ${entry.name} reaches depth ${entry.maxDepth}`,
|
|
96
|
+
data: {
|
|
97
|
+
name: entry.name,
|
|
98
|
+
maxDepth: entry.maxDepth,
|
|
99
|
+
reachablePackages: entry.reachablePackages,
|
|
100
|
+
rootInstances: entry.rootInstances,
|
|
101
|
+
},
|
|
102
|
+
}));
|
|
103
|
+
return [...duplicateDiagnostics, ...depthDiagnostics].slice(0, 10);
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
const describeTopLevelDependency = (name, packagesByName, packageByKey) => {
|
|
107
|
+
const roots = packagesByName.get(name);
|
|
108
|
+
if (roots === undefined || roots.length === 0)
|
|
109
|
+
return undefined;
|
|
110
|
+
const visited = new Set();
|
|
111
|
+
const queue = roots.map((pkg) => ({ key: packageKey(pkg.name, pkg.version), depth: 0 }));
|
|
112
|
+
let maxDepth = 0;
|
|
113
|
+
while (queue.length > 0) {
|
|
114
|
+
const current = queue.shift();
|
|
115
|
+
if (current === undefined || visited.has(current.key))
|
|
116
|
+
continue;
|
|
117
|
+
visited.add(current.key);
|
|
118
|
+
maxDepth = Math.max(maxDepth, current.depth);
|
|
119
|
+
const pkg = packageByKey.get(current.key);
|
|
120
|
+
if (pkg === undefined)
|
|
121
|
+
continue;
|
|
122
|
+
for (const dependency of pkg.dependencies) {
|
|
123
|
+
for (const nextKey of parseDependencyKeys(dependency, packagesByName)) {
|
|
124
|
+
if (!visited.has(nextKey)) {
|
|
125
|
+
queue.push({ key: nextKey, depth: current.depth + 1 });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
name,
|
|
132
|
+
rootInstances: roots.length,
|
|
133
|
+
maxDepth,
|
|
134
|
+
reachablePackages: visited.size,
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
const parseDependencyKeys = (dependency, packagesByName) => {
|
|
138
|
+
const match = /^(\S+)\s+([^\s]+)(?:\s+\(.+\))?$/.exec(dependency.trim());
|
|
139
|
+
if (match === null)
|
|
140
|
+
return [];
|
|
141
|
+
const name = match[1];
|
|
142
|
+
const version = match[2];
|
|
143
|
+
const exactKey = packageKey(name, version);
|
|
144
|
+
const sameName = packagesByName.get(name) ?? [];
|
|
145
|
+
return sameName.some((pkg) => packageKey(pkg.name, pkg.version) === exactKey)
|
|
146
|
+
? [exactKey]
|
|
147
|
+
: sameName.map((pkg) => packageKey(pkg.name, pkg.version));
|
|
148
|
+
};
|
|
149
|
+
const packageKey = (name, version) => `${name}@${version}`;
|
|
150
|
+
const parseManifestDependencyNames = async (manifestPath) => {
|
|
151
|
+
const raw = await readFile(manifestPath, "utf8");
|
|
152
|
+
const names = new Set();
|
|
153
|
+
let inDependencies = false;
|
|
154
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
155
|
+
const trimmed = line.trim();
|
|
156
|
+
if (trimmed.startsWith("[")) {
|
|
157
|
+
inDependencies =
|
|
158
|
+
/^\[(?:workspace\.)?(?:target\..+\.)?(?:dev-|build-)?dependencies\]$/.test(trimmed);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (!inDependencies || trimmed.length === 0 || trimmed.startsWith("#"))
|
|
162
|
+
continue;
|
|
163
|
+
const match = /^([A-Za-z0-9_-]+)\s*=\s*(.+)$/.exec(trimmed);
|
|
164
|
+
if (match === null)
|
|
165
|
+
continue;
|
|
166
|
+
const key = match[1];
|
|
167
|
+
const value = match[2];
|
|
168
|
+
const packageMatch = /package\s*=\s*"([^"]+)"/.exec(value);
|
|
169
|
+
names.add(packageMatch?.[1] ?? key);
|
|
170
|
+
}
|
|
171
|
+
return names;
|
|
172
|
+
};
|
|
173
|
+
//# sourceMappingURL=rs-de-02-dep-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rs-de-02-dep-tree.js","sourceRoot":"","sources":["../../src/signals/rs-de-02-dep-tree.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Signal } from "@skastr0/pulsar-core/signal";
|
|
2
|
+
import { Schema } from "effect";
|
|
3
|
+
import { RustProjectTag } from "../project.js";
|
|
4
|
+
declare const RsDe03Config: Schema.Struct<{
|
|
5
|
+
exclude_globs: Schema.Array$<typeof Schema.String>;
|
|
6
|
+
warn_feature_count: typeof Schema.Number;
|
|
7
|
+
top_n_diagnostics: typeof Schema.Number;
|
|
8
|
+
}>;
|
|
9
|
+
type RsDe03Config = typeof RsDe03Config.Type;
|
|
10
|
+
interface FeaturePropagation {
|
|
11
|
+
readonly crate: string;
|
|
12
|
+
readonly feature: string;
|
|
13
|
+
readonly targetCrate: string;
|
|
14
|
+
readonly targetFeature: string | undefined;
|
|
15
|
+
readonly optional: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface FeatureCrateSummary {
|
|
18
|
+
readonly crate: string;
|
|
19
|
+
readonly featureCount: number;
|
|
20
|
+
readonly conditionalCompilationSites: number;
|
|
21
|
+
readonly propagatedFeatures: number;
|
|
22
|
+
}
|
|
23
|
+
interface RsDe03Output {
|
|
24
|
+
readonly crates: ReadonlyArray<FeatureCrateSummary>;
|
|
25
|
+
readonly propagationByCrate: ReadonlyMap<string, ReadonlyArray<FeaturePropagation>>;
|
|
26
|
+
readonly totalConditionalCompilationSites: number;
|
|
27
|
+
readonly metadataStatus: "loaded" | "missing";
|
|
28
|
+
readonly analysisMode: "cargo-metadata-plus-cfg-scan";
|
|
29
|
+
}
|
|
30
|
+
export declare const RsDe03: Signal<RsDe03Config, RsDe03Output, RustProjectTag>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=rs-de-03-feature-flags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rs-de-03-feature-flags.d.ts","sourceRoot":"","sources":["../../src/signals/rs-de-03-feature-flags.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,MAAM,EAEZ,MAAM,6BAA6B,CAAA;AAEpC,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEvC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAI9C,QAAA,MAAM,YAAY;;;;EAIhB,CAAA;AACF,KAAK,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAE5C,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC3B;AAED,UAAU,mBAAmB;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,2BAA2B,EAAE,MAAM,CAAA;IAC5C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;CACpC;AAED,UAAU,YAAY;IACpB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAA;IACnD,QAAQ,CAAC,kBAAkB,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAA;IACnF,QAAQ,CAAC,gCAAgC,EAAE,MAAM,CAAA;IACjD,QAAQ,CAAC,cAAc,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC7C,QAAQ,CAAC,YAAY,EAAE,8BAA8B,CAAA;CACtD;AAED,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,YAAY,EAAE,cAAc,CAiHrE,CAAA"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { SignalComputeError, } from "@skastr0/pulsar-core/signal";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { Effect, Schema } from "effect";
|
|
4
|
+
import { workspacePackages } from "../cargo-metadata.js";
|
|
5
|
+
import { RustProjectTag } from "../project.js";
|
|
6
|
+
import { DEFAULT_RUST_EXCLUDE_GLOBS } from "./shared-rust-ast.js";
|
|
7
|
+
import { isExcluded, normalizePath } from "./shared-globs.js";
|
|
8
|
+
const RsDe03Config = Schema.Struct({
|
|
9
|
+
exclude_globs: Schema.Array(Schema.String),
|
|
10
|
+
warn_feature_count: Schema.Number,
|
|
11
|
+
top_n_diagnostics: Schema.Number,
|
|
12
|
+
});
|
|
13
|
+
export const RsDe03 = {
|
|
14
|
+
id: "RS-DE-03-feature-flags",
|
|
15
|
+
title: "Feature flag complexity",
|
|
16
|
+
aliases: ["RS-DE-03"],
|
|
17
|
+
tier: 1,
|
|
18
|
+
category: "dependency-entropy",
|
|
19
|
+
kind: "structural",
|
|
20
|
+
configSchema: RsDe03Config,
|
|
21
|
+
defaultConfig: {
|
|
22
|
+
exclude_globs: [...DEFAULT_RUST_EXCLUDE_GLOBS],
|
|
23
|
+
warn_feature_count: 8,
|
|
24
|
+
top_n_diagnostics: 10,
|
|
25
|
+
},
|
|
26
|
+
inputs: [],
|
|
27
|
+
compute: (config) => Effect.gen(function* () {
|
|
28
|
+
const project = yield* RustProjectTag;
|
|
29
|
+
return yield* Effect.tryPromise({
|
|
30
|
+
try: async () => {
|
|
31
|
+
if (project.cargoMetadata === undefined) {
|
|
32
|
+
return {
|
|
33
|
+
crates: [],
|
|
34
|
+
propagationByCrate: new Map(),
|
|
35
|
+
totalConditionalCompilationSites: 0,
|
|
36
|
+
metadataStatus: "missing",
|
|
37
|
+
analysisMode: "cargo-metadata-plus-cfg-scan",
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const packages = workspacePackages(project.cargoMetadata);
|
|
41
|
+
const propagationByCrate = new Map();
|
|
42
|
+
const conditionalSitesByCrate = new Map();
|
|
43
|
+
for (const manifest of project.manifests) {
|
|
44
|
+
if (manifest.packageName === undefined)
|
|
45
|
+
continue;
|
|
46
|
+
const files = project.sourceFiles.filter((file) => {
|
|
47
|
+
const normalizedFile = normalizePath(file);
|
|
48
|
+
return normalizedFile.startsWith(`${normalizePath(manifest.path)}/`);
|
|
49
|
+
});
|
|
50
|
+
let siteCount = 0;
|
|
51
|
+
for (const file of files) {
|
|
52
|
+
if (isExcluded(file, config.exclude_globs))
|
|
53
|
+
continue;
|
|
54
|
+
siteCount += countFeatureConditionals(await readFile(file, "utf8"));
|
|
55
|
+
}
|
|
56
|
+
conditionalSitesByCrate.set(manifest.packageName, siteCount);
|
|
57
|
+
}
|
|
58
|
+
const crates = packages
|
|
59
|
+
.map((pkg) => {
|
|
60
|
+
const propagations = Object.entries(pkg.features).flatMap(([feature, enables]) => enables.flatMap((enable) => {
|
|
61
|
+
const parsed = parseFeatureEnable(enable);
|
|
62
|
+
if (parsed === undefined)
|
|
63
|
+
return [];
|
|
64
|
+
return [
|
|
65
|
+
{
|
|
66
|
+
crate: pkg.name,
|
|
67
|
+
feature,
|
|
68
|
+
targetCrate: parsed.targetCrate,
|
|
69
|
+
targetFeature: parsed.targetFeature,
|
|
70
|
+
optional: parsed.optional,
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
}));
|
|
74
|
+
propagationByCrate.set(pkg.name, propagations);
|
|
75
|
+
return {
|
|
76
|
+
crate: pkg.name,
|
|
77
|
+
featureCount: Object.keys(pkg.features).length,
|
|
78
|
+
conditionalCompilationSites: conditionalSitesByCrate.get(pkg.name) ?? 0,
|
|
79
|
+
propagatedFeatures: propagations.length,
|
|
80
|
+
};
|
|
81
|
+
})
|
|
82
|
+
.sort((left, right) => right.featureCount - left.featureCount || left.crate.localeCompare(right.crate));
|
|
83
|
+
return {
|
|
84
|
+
crates,
|
|
85
|
+
propagationByCrate,
|
|
86
|
+
totalConditionalCompilationSites: crates.reduce((sum, entry) => sum + entry.conditionalCompilationSites, 0),
|
|
87
|
+
metadataStatus: "loaded",
|
|
88
|
+
analysisMode: "cargo-metadata-plus-cfg-scan",
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
catch: (cause) => new SignalComputeError({ signalId: "RS-DE-03-feature-flags", message: String(cause), cause }),
|
|
92
|
+
});
|
|
93
|
+
}),
|
|
94
|
+
score: (out) => {
|
|
95
|
+
if (out.crates.length === 0)
|
|
96
|
+
return 1;
|
|
97
|
+
const maxFeatureCount = out.crates.reduce((max, entry) => Math.max(max, entry.featureCount), 0);
|
|
98
|
+
const penalty = Math.min(1, Math.max(0, maxFeatureCount - 4) / 12);
|
|
99
|
+
return Math.max(0, 1 - penalty);
|
|
100
|
+
},
|
|
101
|
+
diagnose: (out) => {
|
|
102
|
+
if (out.metadataStatus === "missing") {
|
|
103
|
+
return [{ severity: "warn", message: "RS-DE-03 could not load cargo metadata for feature analysis" }];
|
|
104
|
+
}
|
|
105
|
+
return out.crates.slice(0, 10).map((entry) => ({
|
|
106
|
+
severity: entry.featureCount >= 8 ? "warn" : "info",
|
|
107
|
+
message: `Crate ${entry.crate} defines ${entry.featureCount} features (${entry.propagatedFeatures} cross-crate propagations)`,
|
|
108
|
+
data: {
|
|
109
|
+
crate: entry.crate,
|
|
110
|
+
featureCount: entry.featureCount,
|
|
111
|
+
conditionalCompilationSites: entry.conditionalCompilationSites,
|
|
112
|
+
propagatedFeatures: entry.propagatedFeatures,
|
|
113
|
+
analysisMode: out.analysisMode,
|
|
114
|
+
},
|
|
115
|
+
}));
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
const parseFeatureEnable = (value) => {
|
|
119
|
+
const dependencyFeatureMatch = /^(\S+?)(\?)?\/(\S+)$/.exec(value);
|
|
120
|
+
if (dependencyFeatureMatch !== null) {
|
|
121
|
+
return {
|
|
122
|
+
targetCrate: dependencyFeatureMatch[1],
|
|
123
|
+
targetFeature: dependencyFeatureMatch[3],
|
|
124
|
+
optional: dependencyFeatureMatch[2] === "?",
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
if (/^[A-Za-z_][A-Za-z0-9_-]*$/.test(value)) {
|
|
128
|
+
return { targetCrate: value, targetFeature: undefined, optional: false };
|
|
129
|
+
}
|
|
130
|
+
return undefined;
|
|
131
|
+
};
|
|
132
|
+
const countFeatureConditionals = (source) => {
|
|
133
|
+
const matches = [
|
|
134
|
+
...source.matchAll(/#\s*\[\s*cfg(?:_attr)?\s*\([^\]]*feature\s*=\s*"[^"]+"/g),
|
|
135
|
+
...source.matchAll(/\bcfg!\s*\([^)]*feature\s*=\s*"[^"]+"/g),
|
|
136
|
+
];
|
|
137
|
+
return matches.length;
|
|
138
|
+
};
|
|
139
|
+
//# sourceMappingURL=rs-de-03-feature-flags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rs-de-03-feature-flags.js","sourceRoot":"","sources":["../../src/signals/rs-de-03-feature-flags.ts"],"names":[],"mappings":"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"}
|