@omne-harness/repo-toolchain 0.0.11 → 0.0.13
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/README.md +15 -3
- package/README_ZH.md +22 -8
- package/dist/arch/conformance-model.d.ts +12 -2
- package/dist/arch/conformance-model.d.ts.map +1 -1
- package/dist/arch/conformance-model.js.map +1 -1
- package/dist/arch/conformance.d.ts +9 -3
- package/dist/arch/conformance.d.ts.map +1 -1
- package/dist/arch/conformance.js +26 -13
- package/dist/arch/conformance.js.map +1 -1
- package/dist/arch/constraints.d.ts +20 -1
- package/dist/arch/constraints.d.ts.map +1 -1
- package/dist/arch/constraints.js +156 -53
- package/dist/arch/constraints.js.map +1 -1
- package/dist/arch/directions.d.ts +81 -0
- package/dist/arch/directions.d.ts.map +1 -0
- package/dist/arch/directions.js +221 -0
- package/dist/arch/directions.js.map +1 -0
- package/dist/arch/report.d.ts.map +1 -1
- package/dist/arch/report.js +5 -6
- package/dist/arch/report.js.map +1 -1
- package/dist/core/version-files.d.ts +11 -0
- package/dist/core/version-files.d.ts.map +1 -0
- package/dist/core/version-files.js +115 -0
- package/dist/core/version-files.js.map +1 -0
- package/dist/deps/cli.js +32 -7
- package/dist/deps/cli.js.map +1 -1
- package/dist/deps/graph.d.ts +30 -2
- package/dist/deps/graph.d.ts.map +1 -1
- package/dist/deps/graph.js +38 -14
- package/dist/deps/graph.js.map +1 -1
- package/dist/loop/hook-measure.d.ts.map +1 -1
- package/dist/loop/hook-measure.js +4 -3
- package/dist/loop/hook-measure.js.map +1 -1
- package/dist/loop/run.d.ts +3 -2
- package/dist/loop/run.d.ts.map +1 -1
- package/dist/loop/run.js +8 -7
- package/dist/loop/run.js.map +1 -1
- package/dist/loop/sensors/conformance.d.ts +6 -2
- package/dist/loop/sensors/conformance.d.ts.map +1 -1
- package/dist/loop/sensors/conformance.js +6 -3
- package/dist/loop/sensors/conformance.js.map +1 -1
- package/dist/metrics/cli.js +4 -1
- package/dist/metrics/cli.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// 方向规则:schema 3 `constraints.json` 的 `directions` 对依赖图里文件级事实的判定。
|
|
2
|
+
// `omne-deps` 的方向发现与架构符合性报告的 `DIRECTION` 行都从这里算,输入是同一份可信 runner 的方向行与
|
|
3
|
+
// 同一份 dependency-cruiser 依赖事实(deps/graph.ts),不另走 arch/extract.ts 的静态抽取。
|
|
4
|
+
import { filePresence } from '../core/version-files.js';
|
|
5
|
+
import { DependencyGraphUnavailable, memberOf, revisionGraph, workingGraph, } from '../deps/graph.js';
|
|
6
|
+
import { matchesRolePath, readRunnerConstraints, roleMember } from './constraints.js';
|
|
7
|
+
export function directionPairs(policy) {
|
|
8
|
+
const roles = new Map(policy.roles.map(role => [role.id, role]));
|
|
9
|
+
const role = (id) => {
|
|
10
|
+
const found = roles.get(id);
|
|
11
|
+
// parseConstraints 已经核对过每个引用;走到这里是把没校验过的值当成了策略。
|
|
12
|
+
if (found === undefined)
|
|
13
|
+
throw new Error(`Unvalidated direction policy: role ${id} not declared`);
|
|
14
|
+
return found;
|
|
15
|
+
};
|
|
16
|
+
return (policy.directions ?? []).flatMap(direction => direction.from.map(role).flatMap(from => direction.to.map(role).map(to => ({
|
|
17
|
+
direction,
|
|
18
|
+
from,
|
|
19
|
+
to,
|
|
20
|
+
fromMember: roleMember(from),
|
|
21
|
+
toMember: roleMember(to),
|
|
22
|
+
}))));
|
|
23
|
+
}
|
|
24
|
+
/** 成员对去重后的个数:`omne-deps` 汇总行用。 */
|
|
25
|
+
export function memberPairCount(pairs) {
|
|
26
|
+
return new Set(pairs.map(pair => `${pair.fromMember}\u0000${pair.toMember}`)).size;
|
|
27
|
+
}
|
|
28
|
+
/** 文件按角色的 `paths` 落在角色里。命中判定与「角色有没有文件」都只用这一条规则,不取最精确的角色。 */
|
|
29
|
+
export const inRole = (path, role) => role.paths.some(pattern => matchesRolePath(path, pattern));
|
|
30
|
+
const byPosition = (a, b) => a.dependency.path.localeCompare(b.dependency.path) ||
|
|
31
|
+
a.dependency.line - b.dependency.line ||
|
|
32
|
+
a.pair.direction.id.localeCompare(b.pair.direction.id) ||
|
|
33
|
+
a.pair.from.id.localeCompare(b.pair.from.id) ||
|
|
34
|
+
a.pair.to.id.localeCompare(b.pair.to.id);
|
|
35
|
+
/**
|
|
36
|
+
* 命中:依赖所在模块落在某对的 from 角色的 `paths` 里,解析后的目标文件所在成员等于该对的 to 成员。
|
|
37
|
+
* 目标在 `src/`、`dist/` 或声明文件里都算同一成员。一处依赖同时命中几对就记几次。
|
|
38
|
+
*/
|
|
39
|
+
function hitsOf(dependencies, pairs) {
|
|
40
|
+
const hits = [];
|
|
41
|
+
for (const dependency of dependencies) {
|
|
42
|
+
const target = memberOf(dependency.resolved)?.path;
|
|
43
|
+
if (target === undefined)
|
|
44
|
+
continue;
|
|
45
|
+
for (const pair of pairs)
|
|
46
|
+
if (pair.toMember === target && inRole(dependency.path, pair.from))
|
|
47
|
+
hits.push({ pair, dependency });
|
|
48
|
+
}
|
|
49
|
+
return hits.sort(byPosition);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* `omne-deps` 与报告共用的判定:同一份方向行、全部角色、同一张图。源角色与目标角色有没有文件用同一条规则判:
|
|
53
|
+
* 图的 `modules` 里有没有文件落在角色的 `paths` 里。成员改名或迁走后,两边都不能以「命中 0 处」通过。
|
|
54
|
+
*/
|
|
55
|
+
export function judgeDirections(policy, graph) {
|
|
56
|
+
const pairs = directionPairs(policy);
|
|
57
|
+
const hits = hitsOf(graph.dependencies, pairs);
|
|
58
|
+
const populated = new Map();
|
|
59
|
+
const isEmpty = (role) => {
|
|
60
|
+
const known = populated.get(role.id);
|
|
61
|
+
if (known !== undefined)
|
|
62
|
+
return !known;
|
|
63
|
+
const found = graph.modules.some(path => inRole(path, role));
|
|
64
|
+
populated.set(role.id, found);
|
|
65
|
+
return !found;
|
|
66
|
+
};
|
|
67
|
+
return pairs.map(pair => {
|
|
68
|
+
const sides = [
|
|
69
|
+
{ side: 'source', role: pair.from },
|
|
70
|
+
{ side: 'target', role: pair.to },
|
|
71
|
+
];
|
|
72
|
+
return {
|
|
73
|
+
pair,
|
|
74
|
+
empty: sides.filter(item => isEmpty(item.role)),
|
|
75
|
+
hits: hits.filter(hit => hit.pair === pair),
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const SIDE_LABEL = { source: '源角色', target: '目标角色' };
|
|
80
|
+
/** 角色没有文件时给人看的原因;`omne-deps` 的发现与报告的未知行用同一句。 */
|
|
81
|
+
const emptyReason = ({ side, role }) => `${SIDE_LABEL[side]} ${role.id} 的 paths 在被检树中匹配不到任何文件,不能判方向`;
|
|
82
|
+
/**
|
|
83
|
+
* `omne-deps` 的发现:每处命中一条 `direction-rule`,`rule` 是方向行 id,`sites` 是导入处;
|
|
84
|
+
* 源角色或目标角色没有文件的每个(方向行,角色)一条 `direction-unknown`。
|
|
85
|
+
*/
|
|
86
|
+
export function directionFindings(judgements) {
|
|
87
|
+
const unknown = new Map();
|
|
88
|
+
for (const { pair, empty } of judgements)
|
|
89
|
+
for (const item of empty) {
|
|
90
|
+
const key = `${pair.direction.id}\u0000${item.side}\u0000${item.role.id}`;
|
|
91
|
+
if (!unknown.has(key))
|
|
92
|
+
unknown.set(key, {
|
|
93
|
+
kind: 'direction-unknown',
|
|
94
|
+
rule: pair.direction.id,
|
|
95
|
+
message: `[${pair.direction.id}] ${emptyReason(item)}:${pair.direction.source}`,
|
|
96
|
+
sites: [],
|
|
97
|
+
edges: [],
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const hits = judgements
|
|
101
|
+
.flatMap(judgement => judgement.hits)
|
|
102
|
+
.sort(byPosition)
|
|
103
|
+
.map(({ pair, dependency }) => ({
|
|
104
|
+
kind: 'direction-rule',
|
|
105
|
+
rule: pair.direction.id,
|
|
106
|
+
message: `[${pair.direction.id}] ${dependency.path} 依赖了 ${dependency.resolved}(${pair.from.id} → ${pair.to.id}):${pair.direction.source}`,
|
|
107
|
+
sites: [{ path: dependency.path, line: dependency.line, specifier: dependency.specifier }],
|
|
108
|
+
edges: [{ from: pair.fromMember, to: pair.toMember }],
|
|
109
|
+
}));
|
|
110
|
+
return [...unknown.values(), ...hits];
|
|
111
|
+
}
|
|
112
|
+
/** 只把 dependency-cruiser 或 Git 的已知失败记成不可得;别的异常照常抛出。 */
|
|
113
|
+
export function directionFacts(read) {
|
|
114
|
+
try {
|
|
115
|
+
return { kind: 'graph', graph: read() };
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
if (error instanceof DependencyGraphUnavailable)
|
|
119
|
+
return { kind: 'unavailable', reason: error.message };
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** 某个版本的依赖图:工作树取当前树(含未提交的改动),历史版本取那个提交。取哪一版只在这里决定。 */
|
|
124
|
+
export function versionGraph(root, source) {
|
|
125
|
+
return source.kind === 'worktree' ? workingGraph(root) : revisionGraph(root, source.commit);
|
|
126
|
+
}
|
|
127
|
+
/** 有图时一对的状态与原因:有角色没有文件为 unknown,没有命中为 converged,有命中为 deviation。 */
|
|
128
|
+
function judgedState({ empty, hits, }) {
|
|
129
|
+
if (empty.length > 0)
|
|
130
|
+
return ['unknown', empty.map(emptyReason).join(';')];
|
|
131
|
+
if (hits.length === 0)
|
|
132
|
+
return ['converged', '该成员对的已解析源码导入没有指向目标成员;不表示整体符合'];
|
|
133
|
+
return [
|
|
134
|
+
'deviation',
|
|
135
|
+
`${hits.length} 处依赖了目标成员:${hits
|
|
136
|
+
.map(hit => `${hit.dependency.path}:${hit.dependency.line} → ${hit.dependency.resolved}`)
|
|
137
|
+
.join(';')}`,
|
|
138
|
+
];
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* 架构符合性报告的方向行:每对一行。没有命中为 converged;有命中为 deviation,`reason` 逐处列源文件、
|
|
142
|
+
* 目标文件与行号;源角色或目标角色在被检版本里没有文件、或依赖事实不可得时为 unknown 并写明原因。`age` 一律 unjudged,
|
|
143
|
+
* 由 `directionConformance` 对基线判。
|
|
144
|
+
*/
|
|
145
|
+
export function directionRows(policy, facts) {
|
|
146
|
+
const judgements = facts.kind === 'graph'
|
|
147
|
+
? judgeDirections(policy, facts.graph)
|
|
148
|
+
: directionPairs(policy).map(pair => ({ pair, empty: [], hits: [] }));
|
|
149
|
+
return judgements.map(judgement => {
|
|
150
|
+
const { pair, hits } = judgement;
|
|
151
|
+
const { direction, from, to } = pair;
|
|
152
|
+
const [state, reason] = facts.kind === 'unavailable'
|
|
153
|
+
? ['unknown', `依赖事实不可得:${facts.reason}`]
|
|
154
|
+
: judgedState(judgement);
|
|
155
|
+
return {
|
|
156
|
+
id: JSON.stringify(['DIRECTION', direction.id, from.id, to.id]),
|
|
157
|
+
rule: 'DIRECTION',
|
|
158
|
+
state,
|
|
159
|
+
age: 'unjudged',
|
|
160
|
+
member: pair.fromMember,
|
|
161
|
+
targetMember: pair.toMember,
|
|
162
|
+
key: `${direction.id} ${from.id} → ${to.id}`,
|
|
163
|
+
reason,
|
|
164
|
+
expected: direction.source,
|
|
165
|
+
sites: hits.map(hit => ({ path: hit.dependency.path, line: hit.dependency.line })),
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 某个版本里,方向行引用的角色有没有一个在文件清单里匹配得到文件;找到一个就停。清单(工作树的磁盘、提交的
|
|
171
|
+
* `git ls-tree`)覆盖这个版本依赖图的 `modules`,所以这里回答「没有」时图里也没有。判定见 core/version-files.ts,
|
|
172
|
+
* 与 `inRole` 用同一套 `paths` 写法。
|
|
173
|
+
*/
|
|
174
|
+
function anyRoleHasFiles(root, source, policy) {
|
|
175
|
+
const roles = new Map(directionPairs(policy)
|
|
176
|
+
.flatMap(({ from, to }) => [from, to])
|
|
177
|
+
.map(role => [role.id, role]));
|
|
178
|
+
const present = filePresence(root, source);
|
|
179
|
+
return [...roles.values()].some(role => present(role.paths));
|
|
180
|
+
}
|
|
181
|
+
/** 方向行引用的角色都没有文件时的依赖事实:没有文件,也就没有依赖。 */
|
|
182
|
+
const NO_FILES = {
|
|
183
|
+
modules: [],
|
|
184
|
+
dependencies: [],
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* 报告的方向行一节。方向行与角色只从可信 runner 的 `constraints.json` 读(全部角色,不按退休过滤),
|
|
188
|
+
* 与 `omne-deps` 同一份;runner 没有文件或没有方向行就没有这一节,也不取依赖图。
|
|
189
|
+
* 被检版本与基线版本都用这份方向行,依赖事实各取各的版本:`graph` 是调用方已经算好的被检版本的图。
|
|
190
|
+
* 没给 `graph` 时先按路径看:方向行引用的角色在这个版本的文件清单里都匹配不到文件,就不取图,每一行都是两边角色都没有
|
|
191
|
+
* 文件的 unknown,与取图的结果逐字相同(清单覆盖图的 `modules`,清单里没有的图里也没有)。有一个角色有文件、或清单读不确定,
|
|
192
|
+
* 就照常取图。不取图时看不到取图会遇到的失败(预设坏了、缓存坏了),行写路径原因:结果本来就与图无关。
|
|
193
|
+
* `root` 不必是仓库顶层:清单与取图都按 `root` 下的相对路径读同一棵树。基线版本独立判断。给了基线时偏离行判新旧;基线的图不可得就不判,`age` 留 unjudged,每一行的 `reason` 末尾写明基线依赖事实不可得及原因。
|
|
194
|
+
*/
|
|
195
|
+
export function directionConformance(input) {
|
|
196
|
+
const runner = readRunnerConstraints();
|
|
197
|
+
if (runner.kind === 'missing' || (runner.value.directions ?? []).length === 0)
|
|
198
|
+
return [];
|
|
199
|
+
const policy = runner.value;
|
|
200
|
+
const readGraph = input.readGraph ?? versionGraph;
|
|
201
|
+
const factsOf = (source) => anyRoleHasFiles(input.root, source, policy)
|
|
202
|
+
? directionFacts(() => readGraph(input.root, source))
|
|
203
|
+
: { kind: 'graph', graph: NO_FILES };
|
|
204
|
+
const rows = directionRows(policy, input.graph === undefined ? factsOf(input.current) : { kind: 'graph', graph: input.graph });
|
|
205
|
+
if (input.baseline === undefined)
|
|
206
|
+
return rows;
|
|
207
|
+
const stock = factsOf(input.baseline);
|
|
208
|
+
if (stock.kind === 'unavailable')
|
|
209
|
+
return rows.map(row => ({
|
|
210
|
+
...row,
|
|
211
|
+
reason: `${row.reason};基线依赖事实不可得,偏离行未判新旧:${stock.reason}`,
|
|
212
|
+
}));
|
|
213
|
+
const stockIds = new Set(directionRows(policy, stock)
|
|
214
|
+
.filter(row => row.state === 'deviation')
|
|
215
|
+
.map(row => row.id));
|
|
216
|
+
return rows.map(row => ({
|
|
217
|
+
...row,
|
|
218
|
+
age: row.state !== 'deviation' ? 'unjudged' : stockIds.has(row.id) ? 'stock' : 'new',
|
|
219
|
+
}));
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=directions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directions.js","sourceRoot":"","sources":["../../src/arch/directions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/arch/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC7B,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAe,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/arch/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC7B,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAe,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAEzD,kGAAkG;AAClG,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,uBAAuB,EAC9B,MAAM,EAAE,aAAa,GACpB;IAAE,QAAQ,EAAE,0BAA0B,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,CAgDpF"}
|
package/dist/arch/report.js
CHANGED
|
@@ -2,8 +2,8 @@ import { actualArchitectureOf, compareActualArchitectures, } from './actual.js';
|
|
|
2
2
|
import { readArchitectureSource } from './source.js';
|
|
3
3
|
import { productSource } from './resolve.js';
|
|
4
4
|
import { buildReport } from '../metrics/report.js';
|
|
5
|
-
import { revisionGraph, workingGraph } from '../deps/graph.js';
|
|
6
5
|
import { conformanceOf } from './conformance.js';
|
|
6
|
+
import { versionGraph } from './directions.js';
|
|
7
7
|
/** Read each version once. Architecture and function differences use the exact same snapshots. */
|
|
8
8
|
export function readArchitectureReport(input, config) {
|
|
9
9
|
const currentSource = readArchitectureSource(input.root, input.revision);
|
|
@@ -38,15 +38,14 @@ export function readArchitectureReport(input, config) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
+
// 与抽取同一个版本的图:符合性的方向行与度量读同一张。
|
|
42
|
+
const graph = versionGraph(input.root, currentSource.source);
|
|
41
43
|
return {
|
|
42
44
|
document,
|
|
43
|
-
conformance: conformanceOf(input.root, currentSource, baselineSource),
|
|
45
|
+
conformance: conformanceOf(input.root, currentSource, baselineSource, graph),
|
|
44
46
|
report: buildReport({
|
|
45
47
|
files,
|
|
46
|
-
|
|
47
|
-
graph: input.revision === undefined
|
|
48
|
-
? workingGraph(input.root)
|
|
49
|
-
: revisionGraph(input.root, input.revision),
|
|
48
|
+
graph,
|
|
50
49
|
thresholds: config.thresholds,
|
|
51
50
|
bands: config.bands,
|
|
52
51
|
...(baselineSource === undefined ? {} : { changed, baseTexts }),
|
package/dist/arch/report.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/arch/report.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAG3B,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAe,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/arch/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** 要查的版本:工作树(含未提交的改动),或某个提交。 */
|
|
2
|
+
export interface FileVersion {
|
|
3
|
+
readonly kind: 'worktree' | 'revision';
|
|
4
|
+
readonly commit: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* 回答「这个版本在 `patterns` 下可能有文件吗」的函数。`patterns` 用架构角色 `paths` 的写法:末尾 `/**` 是那个目录之下的
|
|
8
|
+
* 任何文件,否则是精确路径(arch/constraints.ts 的 `matchesRolePath`)。同一个版本的 Git 查询结果在函数里复用。
|
|
9
|
+
*/
|
|
10
|
+
export declare function filePresence(root: string, version: FileVersion): (patterns: readonly string[]) => boolean;
|
|
11
|
+
//# sourceMappingURL=version-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-files.d.ts","sourceRoot":"","sources":["../../src/core/version-files.ts"],"names":[],"mappings":"AAQA,gCAAgC;AAChC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAA;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,GACnB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAI1C"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// 某个版本在一组路径下有没有文件:工作树查磁盘,提交查 Git 树。架构符合性报告据此决定方向行要不要取依赖图
|
|
2
|
+
// (arch/directions.ts),所以只在确知没有时回答「没有」:读不了、Git 失败、提交不在、链接或子模块挡住了视线,都回答「有」,
|
|
3
|
+
// 交给取图。路径相对 `root`;Git 命令以 `root` 为工作目录、路径按工作目录解释,与 deps/graph.ts 导出提交的方式相同,
|
|
4
|
+
// 所以 `root` 不必是仓库顶层。
|
|
5
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import { git } from './git.js';
|
|
8
|
+
/**
|
|
9
|
+
* 回答「这个版本在 `patterns` 下可能有文件吗」的函数。`patterns` 用架构角色 `paths` 的写法:末尾 `/**` 是那个目录之下的
|
|
10
|
+
* 任何文件,否则是精确路径(arch/constraints.ts 的 `matchesRolePath`)。同一个版本的 Git 查询结果在函数里复用。
|
|
11
|
+
*/
|
|
12
|
+
export function filePresence(root, version) {
|
|
13
|
+
const present = version.kind === 'worktree' ? workingTreePresence(root) : revisionPresence(root, version.commit);
|
|
14
|
+
return patterns => patterns.some(present);
|
|
15
|
+
}
|
|
16
|
+
/** 读磁盘时确知「没有」的两种失败:路径不存在,或路径上某一段不是目录。 */
|
|
17
|
+
function absent(error) {
|
|
18
|
+
return (error instanceof Error &&
|
|
19
|
+
'code' in error &&
|
|
20
|
+
(error.code === 'ENOENT' || error.code === 'ENOTDIR'));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 工作树:目录模式从静态前缀往下找,遇到第一个不是目录的项(文件、链接或别的)就停。经过链接的路径照常跟进,
|
|
24
|
+
* dependency-cruiser 也走进链接的目录。精确路径跟随链接后不是目录才算有:依赖图里只有文件。
|
|
25
|
+
*/
|
|
26
|
+
function workingTreePresence(root) {
|
|
27
|
+
const walk = (directory) => {
|
|
28
|
+
let entries;
|
|
29
|
+
try {
|
|
30
|
+
entries = readdirSync(join(root, directory), { withFileTypes: true });
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
return !absent(error);
|
|
34
|
+
}
|
|
35
|
+
return entries.some(entry => !entry.isDirectory() || walk(`${directory}/${entry.name}`));
|
|
36
|
+
};
|
|
37
|
+
return pattern => {
|
|
38
|
+
if (pattern.endsWith('/**'))
|
|
39
|
+
return walk(pattern.slice(0, -3));
|
|
40
|
+
try {
|
|
41
|
+
return !statSync(join(root, pattern)).isDirectory();
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
return !absent(error);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** `a/b/c` 与它的上级:`a`、`a/b`、`a/b/c`。 */
|
|
49
|
+
const withAncestors = (path) => path.split('/').map((_, index, parts) => parts.slice(0, index + 1).join('/'));
|
|
50
|
+
/**
|
|
51
|
+
* 提交:从最上一级往下逐段看在提交树里是什么。缺了就没有;普通文件挡在路径上,下面不会有文件;链接与子模块(`120000`、
|
|
52
|
+
* `160000`)后面依赖图可能还有文件,Git 却不走进去,按有处理。目录模式的前缀是目录时,再看
|
|
53
|
+
* `git ls-tree -r --name-only` 列不列得出东西。精确路径是普通文件、链接或子模块算有,是目录算没有。
|
|
54
|
+
*/
|
|
55
|
+
function revisionPresence(root, commit) {
|
|
56
|
+
/** 跑一条 git;失败为 undefined,由调用处按「有」处理。 */
|
|
57
|
+
const run = (args) => {
|
|
58
|
+
try {
|
|
59
|
+
return git(root, args);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
// 提交本身不在,或那个对象不是提交(树、文件):依赖图同样认它不出,交给取图记成不可得。
|
|
66
|
+
const isCommit = run(['rev-parse', '--verify', '--quiet', `${commit}^{commit}`]) !== undefined;
|
|
67
|
+
const entries = new Map();
|
|
68
|
+
const entryOf = (path) => {
|
|
69
|
+
if (entries.has(path))
|
|
70
|
+
return entries.get(path);
|
|
71
|
+
const line = run(['--literal-pathspecs', 'ls-tree', commit, '--', path]);
|
|
72
|
+
const mode = line?.split(' ', 1)[0];
|
|
73
|
+
const entry = line === undefined
|
|
74
|
+
? undefined
|
|
75
|
+
: line === ''
|
|
76
|
+
? 'missing'
|
|
77
|
+
: mode === '040000'
|
|
78
|
+
? 'tree'
|
|
79
|
+
: mode === '100644' || mode === '100755'
|
|
80
|
+
? 'file'
|
|
81
|
+
: 'opaque';
|
|
82
|
+
entries.set(path, entry);
|
|
83
|
+
return entry;
|
|
84
|
+
};
|
|
85
|
+
return pattern => {
|
|
86
|
+
if (!isCommit)
|
|
87
|
+
return true;
|
|
88
|
+
const exact = !pattern.endsWith('/**');
|
|
89
|
+
const target = exact ? pattern : pattern.slice(0, -3);
|
|
90
|
+
for (const path of withAncestors(target)) {
|
|
91
|
+
const entry = entryOf(path);
|
|
92
|
+
if (entry === undefined || entry === 'opaque')
|
|
93
|
+
return true;
|
|
94
|
+
if (entry === 'missing')
|
|
95
|
+
return false;
|
|
96
|
+
// 普通文件:是精确路径本身就有;挡在路径上或就是目录前缀,下面都不会有文件。
|
|
97
|
+
if (entry === 'file')
|
|
98
|
+
return exact && path === target;
|
|
99
|
+
}
|
|
100
|
+
// 走到这里,目标与它的上级都是目录。精确路径是目录,依赖图里不会有它。
|
|
101
|
+
if (exact)
|
|
102
|
+
return false;
|
|
103
|
+
const listed = run([
|
|
104
|
+
'--literal-pathspecs',
|
|
105
|
+
'ls-tree',
|
|
106
|
+
'-r',
|
|
107
|
+
'--name-only',
|
|
108
|
+
commit,
|
|
109
|
+
'--',
|
|
110
|
+
target,
|
|
111
|
+
]);
|
|
112
|
+
return listed === undefined || listed !== '';
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=version-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-files.js","sourceRoot":"","sources":["../../src/core/version-files.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,2EAA2E;AAC3E,6EAA6E;AAC7E,qBAAqB;AACrB,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAQ9B;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,OAAoB;IAEpB,MAAM,OAAO,GACX,OAAO,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IAClG,OAAO,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AAC3C,CAAC;AAED,yCAAyC;AACzC,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,CACL,KAAK,YAAY,KAAK;QACtB,MAAM,IAAI,KAAK;QACf,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CACtD,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,IAAY;IACvC,MAAM,IAAI,GAAG,CAAC,SAAiB,EAAW,EAAE;QAC1C,IAAI,OAAO,CAAA;QACX,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;QACvE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACvB,CAAC;QACD,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,GAAG,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAC1F,CAAC,CAAA;IACD,OAAO,OAAO,CAAC,EAAE;QACf,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAC9D,IAAI,CAAC;YACH,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QACrD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAED,uCAAuC;AACvC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAY,EAAE,CAC/C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAK/E;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,IAAY,EAAE,MAAc;IACpD,wCAAwC;IACxC,MAAM,GAAG,GAAG,CAAC,IAAuB,EAAsB,EAAE;QAC1D,IAAI,CAAC;YACH,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACxB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC,CAAA;IACD,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,WAAW,CAAC,CAAC,KAAK,SAAS,CAAA;IAC9F,MAAM,OAAO,GAAG,IAAI,GAAG,EAA6B,CAAA;IACpD,MAAM,OAAO,GAAG,CAAC,IAAY,EAAqB,EAAE;QAClD,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,qBAAqB,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;QACxE,MAAM,IAAI,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,KAAK,GACT,IAAI,KAAK,SAAS;YAChB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,IAAI,KAAK,EAAE;gBACX,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,IAAI,KAAK,QAAQ;oBACjB,CAAC,CAAC,MAAM;oBACR,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ;wBACtC,CAAC,CAAC,MAAM;wBACR,CAAC,CAAC,QAAQ,CAAA;QACpB,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACxB,OAAO,KAAK,CAAA;IACd,CAAC,CAAA;IACD,OAAO,OAAO,CAAC,EAAE;QACf,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAA;QAC1B,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACtC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrD,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;YAC3B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAA;YAC1D,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,KAAK,CAAA;YACrC,wCAAwC;YACxC,IAAI,KAAK,KAAK,MAAM;gBAAE,OAAO,KAAK,IAAI,IAAI,KAAK,MAAM,CAAA;QACvD,CAAC;QACD,qCAAqC;QACrC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAA;QACvB,MAAM,MAAM,GAAG,GAAG,CAAC;YACjB,qBAAqB;YACrB,SAAS;YACT,IAAI;YACJ,aAAa;YACb,MAAM;YACN,IAAI;YACJ,MAAM;SACP,CAAC,CAAA;QACF,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE,CAAA;IAC9C,CAAC,CAAA;AACH,CAAC"}
|
package/dist/deps/cli.js
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// `pnpm run lint:deps`:dependency-cruiser
|
|
3
|
-
//
|
|
2
|
+
// `pnpm run lint:deps`:dependency-cruiser 的规则违规、成员与组之间的环,以及 `constraints.json`(schema 3)方向行的命中。
|
|
3
|
+
// 有任何一项退出 1,工具出错退出 2。与 clean loop、`pnpm run metrics` 读同一张图(deps/graph.ts);
|
|
4
|
+
// 预设与方向行都只从运行检查器的仓库读(core/subject.ts),`--root` 只改变被检查的树。
|
|
4
5
|
import { resolve } from 'node:path';
|
|
6
|
+
import { readRunnerConstraints } from '../arch/constraints.js';
|
|
7
|
+
import { directionFindings, directionPairs, judgeDirections, memberPairCount, } from '../arch/directions.js';
|
|
5
8
|
import { workingGraph } from './graph.js';
|
|
6
9
|
const USAGE = '用法:[--root <检出目录>]';
|
|
10
|
+
/** 方向行的检查结果与给人看的那一行;runner 没有 constraints.json 或文件是 schema 1、2 时不检查。 */
|
|
11
|
+
function directionCheck(constraints, graph) {
|
|
12
|
+
if (constraints.kind === 'missing')
|
|
13
|
+
return { findings: [], summary: `依赖方向:runner 没有 ${constraints.path},未检查` };
|
|
14
|
+
const pairs = directionPairs(constraints.value);
|
|
15
|
+
if (pairs.length === 0)
|
|
16
|
+
return { findings: [], summary: `依赖方向:${constraints.path} 没有方向行` };
|
|
17
|
+
const findings = directionFindings(judgeDirections(constraints.value, graph));
|
|
18
|
+
const unknown = findings.filter(finding => finding.kind === 'direction-unknown').length;
|
|
19
|
+
return {
|
|
20
|
+
findings,
|
|
21
|
+
summary: `依赖方向:检查了 ${constraints.value.directions?.length ?? 0} 条方向行、${memberPairCount(pairs)} 个成员对,命中 ${findings.length - unknown} 处${unknown === 0 ? '' : `,${unknown} 处角色没有文件`}`,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
7
24
|
function main(argv) {
|
|
8
25
|
let root = process.cwd();
|
|
9
26
|
for (let index = 0; index < argv.length; index += 1) {
|
|
@@ -13,15 +30,23 @@ function main(argv) {
|
|
|
13
30
|
root = resolve(value);
|
|
14
31
|
index += 1;
|
|
15
32
|
}
|
|
33
|
+
// 先读 runner 的方向行:文件坏了直接退出 2,不先跑一遍 dependency-cruiser。
|
|
34
|
+
const constraints = readRunnerConstraints();
|
|
16
35
|
const graph = workingGraph(root);
|
|
17
|
-
|
|
36
|
+
const directions = directionCheck(constraints, graph);
|
|
37
|
+
const findings = [
|
|
38
|
+
...graph.findings,
|
|
39
|
+
...directions.findings,
|
|
40
|
+
];
|
|
41
|
+
for (const finding of findings) {
|
|
18
42
|
const at = finding.sites[0];
|
|
19
43
|
console.log(` error ${finding.message}${at === undefined ? '' : `(${at.path}:${at.line})`}`);
|
|
20
44
|
}
|
|
21
|
-
console.log(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
45
|
+
console.log(directions.summary);
|
|
46
|
+
console.log(findings.length === 0
|
|
47
|
+
? `✔ 没有依赖违规、方向命中,也没有成员或组之间的环(${graph.members.length} 个成员、${graph.edges.length} 条成员边)`
|
|
48
|
+
: `✗ ${findings.length} 处依赖违规、方向命中或环`);
|
|
49
|
+
return findings.length === 0 ? 0 : 1;
|
|
25
50
|
}
|
|
26
51
|
try {
|
|
27
52
|
process.exitCode = main(process.argv.slice(2));
|
package/dist/deps/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/deps/cli.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/deps/cli.ts"],"names":[],"mappings":";AACA,gGAAgG;AAChG,2EAA2E;AAC3E,yDAAyD;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,qBAAqB,EAA0B,MAAM,wBAAwB,CAAA;AACtF,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,eAAe,GAEhB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,YAAY,EAAgD,MAAM,YAAY,CAAA;AAEvF,MAAM,KAAK,GAAG,oBAAoB,CAAA;AAElC,wEAAwE;AACxE,SAAS,cAAc,CACrB,WAA8B,EAC9B,KAAsB;IAEtB,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS;QAChC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,kBAAkB,WAAW,CAAC,IAAI,MAAM,EAAE,CAAA;IAC5E,MAAM,KAAK,GAAG,cAAc,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;IAC/C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QACpB,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,WAAW,CAAC,IAAI,QAAQ,EAAE,CAAA;IACpE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,eAAe,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;IAC7E,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,mBAAmB,CAAC,CAAC,MAAM,CAAA;IACvF,OAAO;QACL,QAAQ;QACR,OAAO,EAAE,YAAY,WAAW,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,SAAS,eAAe,CAAC,KAAK,CAAC,YAAY,QAAQ,CAAC,MAAM,GAAG,OAAO,KAAK,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,UAAU,EAAE;KACpL,CAAA;AACH,CAAC;AAED,SAAS,IAAI,CAAC,IAAuB;IACnC,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IACxB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;QAC7B,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;YACjE,MAAM,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC,CAAA;QAC1D,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;QACrB,KAAK,IAAI,CAAC,CAAA;IACZ,CAAC;IACD,sDAAsD;IACtD,MAAM,WAAW,GAAG,qBAAqB,EAAE,CAAA;IAC3C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IAChC,MAAM,UAAU,GAAG,cAAc,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IACrD,MAAM,QAAQ,GAAsD;QAClE,GAAG,KAAK,CAAC,QAAQ;QACjB,GAAG,UAAU,CAAC,QAAQ;KACvB,CAAA;IACD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC3B,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,CAAC,OAAO,GAAG,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,CAAA;IAC/F,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;IAC/B,OAAO,CAAC,GAAG,CACT,QAAQ,CAAC,MAAM,KAAK,CAAC;QACnB,CAAC,CAAC,6BAA6B,KAAK,CAAC,OAAO,CAAC,MAAM,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,QAAQ;QACrF,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,eAAe,CACxC,CAAA;IACD,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACtC,CAAC;AAED,IAAI,CAAC;IACH,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AAChD,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IACrE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;AACtB,CAAC"}
|
package/dist/deps/graph.d.ts
CHANGED
|
@@ -17,9 +17,18 @@ export interface MemberEdge {
|
|
|
17
17
|
readonly to: string;
|
|
18
18
|
readonly sites: readonly ImportSite[];
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* 文件级的依赖事实:一个模块里指向别的成员、且已解析的一处导入。不限产品源码,测试与 `src` 下的 testing
|
|
22
|
+
* 入口都在;Node 内建模块与解析失败的导入不在。方向规则(arch/directions.ts)只从这里判命中。
|
|
23
|
+
*/
|
|
24
|
+
export interface FileDependency extends ImportSite {
|
|
25
|
+
/** 解析后的目标文件,仓库相对路径;可以在目标成员的 `src/`、`dist/` 或声明文件里。 */
|
|
26
|
+
readonly resolved: string;
|
|
27
|
+
}
|
|
28
|
+
/** 本模块自己产生的发现种类;方向规则的种类由产生它们的 arch/directions.ts 声明。 */
|
|
20
29
|
export type DependencyFindingKind = 'dependency-rule' | 'file-cycle' | 'member-cycle' | 'group-cycle';
|
|
21
|
-
export interface DependencyFinding {
|
|
22
|
-
readonly kind:
|
|
30
|
+
export interface DependencyFinding<Kind extends string = DependencyFindingKind> {
|
|
31
|
+
readonly kind: Kind;
|
|
23
32
|
/** dependency-cruiser 的规则名;成员环与组环是本模块算的,取 kind。 */
|
|
24
33
|
readonly rule: string;
|
|
25
34
|
readonly message: string;
|
|
@@ -33,9 +42,23 @@ export interface DependencyFinding {
|
|
|
33
42
|
}
|
|
34
43
|
export interface DependencyGraph {
|
|
35
44
|
readonly members: readonly Member[];
|
|
45
|
+
/**
|
|
46
|
+
* 成员目录里 dependency-cruiser 走到或解析到的文件(仓库相对路径,含测试);方向规则据此判源角色与目标角色有没有文件。
|
|
47
|
+
* 解析失败的导入与内建模块的节点不是文件,不在这里。
|
|
48
|
+
*/
|
|
49
|
+
readonly modules: readonly string[];
|
|
36
50
|
readonly edges: readonly MemberEdge[];
|
|
51
|
+
/** 跨成员的文件级依赖事实;`edges` 是其中产品源码部分按成员对的归并。 */
|
|
52
|
+
readonly dependencies: readonly FileDependency[];
|
|
37
53
|
readonly findings: readonly DependencyFinding[];
|
|
38
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* dependency-cruiser 或 Git 的已知失败:图取不到。架构符合性报告据此把方向行记成「依赖事实不可得」;
|
|
57
|
+
* 别的异常不属于这一类,照常抛出。
|
|
58
|
+
*/
|
|
59
|
+
export declare class DependencyGraphUnavailable extends Error {
|
|
60
|
+
readonly name = "DependencyGraphUnavailable";
|
|
61
|
+
}
|
|
39
62
|
/** 路径相对于仓库根。 */
|
|
40
63
|
export declare function memberOf(path: string): Member | undefined;
|
|
41
64
|
/** 强连通分量里节点数大于一的那些,即环;节点按字典序。 */
|
|
@@ -52,6 +75,11 @@ export interface CruiseDependency {
|
|
|
52
75
|
export interface CruiseModule {
|
|
53
76
|
readonly source: string;
|
|
54
77
|
readonly dependencies: readonly CruiseDependency[];
|
|
78
|
+
/**
|
|
79
|
+
* 与依赖上的同名字段同义:解析失败。解析失败的导入也留成节点,`source` 是说明符原文,不是文件。dependency-cruiser
|
|
80
|
+
* 只给依赖到的节点写这个字段,走到的文件没有它,所以可以缺省(与它自己的类型声明一致)。
|
|
81
|
+
*/
|
|
82
|
+
readonly couldNotResolve?: boolean;
|
|
55
83
|
}
|
|
56
84
|
export interface CruiseViolation {
|
|
57
85
|
readonly from: string;
|
package/dist/deps/graph.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/deps/graph.ts"],"names":[],"mappings":"AAwBA,mEAAmE;AACnE,MAAM,WAAW,MAAM;IACrB,sBAAsB;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,4BAA4B;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAA;CACtC;AAED,MAAM,MAAM,qBAAqB,GAC7B,iBAAiB,GACjB,YAAY,GACZ,cAAc,GACd,aAAa,CAAA;AAEjB,MAAM,WAAW,iBAAiB;
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/deps/graph.ts"],"names":[],"mappings":"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"}
|