@webpieces/nx-webpieces-rules 0.4.874 → 0.4.876
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 -7
- package/package.json +7 -7
- package/src/executors/generate/executor.js +4 -3
- package/src/executors/generate/executor.js.map +1 -1
- package/src/executors/visualize/executor.d.ts +8 -5
- package/src/executors/visualize/executor.js +10 -7
- package/src/executors/visualize/executor.js.map +1 -1
- package/src/lib/graph-color-modes.d.ts +3 -3
- package/src/lib/graph-color-modes.js +4 -4
- package/src/lib/graph-color-modes.js.map +1 -1
- package/src/lib/graph-impact.d.ts +168 -40
- package/src/lib/graph-impact.js +326 -74
- package/src/lib/graph-impact.js.map +1 -1
- package/src/lib/graph-legend.js +1 -1
- package/src/lib/graph-legend.js.map +1 -1
- package/src/lib/graph-page-shell.d.ts +6 -0
- package/src/lib/graph-page-shell.js +14 -3
- package/src/lib/graph-page-shell.js.map +1 -1
- package/src/lib/graph-page-styles.js +3 -0
- package/src/lib/graph-page-styles.js.map +1 -1
- package/src/lib/graph-visualizer.client.d.ts +24 -3
- package/src/lib/graph-visualizer.client.js +100 -15
- package/src/lib/graph-visualizer.client.js.map +1 -1
|
@@ -1,40 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Impact mode's data: what
|
|
2
|
+
* Impact mode's data: what one COMPARISON's build looks like, in three shades (plus untouched grey).
|
|
3
3
|
*
|
|
4
|
+
* There are two comparisons, and only two (#1163). Both end at the WORKING TREE, so uncommitted and
|
|
5
|
+
* untracked work counts in either:
|
|
6
|
+
*
|
|
7
|
+
* - BRANCH, "Changed on this branch": the fork point (`DiffScope.detectBase` in rules-config:
|
|
8
|
+
* `git merge-base HEAD origin/main`, falling back to `main`) → working tree.
|
|
9
|
+
* - COMMIT, "Last commit": `HEAD^` → working tree. To see what another commit changed, check it out
|
|
10
|
+
* (`git checkout <hash>`) and run `pnpm arch:visualize`: nx computes `--affected` against the code
|
|
11
|
+
* that is actually on disk, so nothing here ever jumps to another commit.
|
|
12
|
+
*
|
|
13
|
+
* Which of them exist is decided by `ImpactScopeResolver` from where HEAD is. On `main` (by BRANCH
|
|
14
|
+
* NAME, so a local main with unpushed commits still counts as main) and on a detached HEAD only the
|
|
15
|
+
* last commit exists — the fork point IS HEAD there, so the branch comparison would always be empty.
|
|
16
|
+
* On a feature branch with commits past its fork point both exist, the branch one first. On a FRESH
|
|
17
|
+
* feature branch (fork point = HEAD) only the branch one exists: falling through to "last commit"
|
|
18
|
+
* would show main's last PR as if it were the branch's own work.
|
|
19
|
+
*
|
|
20
|
+
* Per comparison:
|
|
4
21
|
* - BUILD INPUT is every transitive dependency of the affected set that is not itself affected:
|
|
5
22
|
* `ci` dependsOn `^build`, so they must exist as build output though their inputs did not change.
|
|
6
23
|
* nx restores them from cache when it has them and compiles them otherwise — which one happens is
|
|
7
24
|
* not knowable here, so nothing claims it. A pure downward walk over the graph's own edges.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
25
|
+
* - AFFECTED is `nx show projects --affected --base=<the comparison's base> --json`, with NO
|
|
26
|
+
* `--head`, so uncommitted and untracked work counts. nx already gets right everything a
|
|
27
|
+
* hand-rolled diff gets wrong: lockfile and package.json changes resolved per project, root/global
|
|
28
|
+
* inputs, namedInputs, implicitDependencies, nested roots and deleted files. This uses its public
|
|
29
|
+
* CLI surface only, never nx internals, and never NX_BASE/NX_HEAD, whose value depends on whoever
|
|
30
|
+
* launched the process.
|
|
14
31
|
* - TOUCHED is the subset of that set which OWNS a changed file, by nx's own file-to-project
|
|
15
32
|
* ownership (the project file map from `createProjectFileMapUsingProjectGraph`, public devkit API)
|
|
16
|
-
* — never a path-prefix guess.
|
|
17
|
-
* (the file is gone), so it shows
|
|
33
|
+
* — never a path-prefix guess. The ownership map is computed ONCE and shared by every comparison.
|
|
34
|
+
* A project whose only change is a DELETED file is not in that map (the file is gone), so it shows
|
|
35
|
+
* as affected rather than touched. The changed-file list is `DiffScope.getChangedFiles`, the same
|
|
36
|
+
* base→working-tree diff (with untracked files) every code rule uses.
|
|
18
37
|
*
|
|
19
|
-
* The
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
38
|
+
* The answer changes per checkout, so it never goes into the committed dependencies.html or
|
|
39
|
+
* dependencies.json (both stay byte-stable). It goes into a SIDECAR,
|
|
40
|
+
* `architecture/.impact/dependencies.impact.js`: a plain script setting one window global,
|
|
41
|
+
* `window.__WP_IMPACT__ = { scans, defaultKind }`, loaded with `<script src>` — the one way a page
|
|
42
|
+
* opened straight from disk (file://) can read a neighbouring file. The directory carries its own
|
|
43
|
+
* `.gitignore` containing `*`, which ignores the directory and everything in it, so a consumer repo
|
|
44
|
+
* needs no gitignore edit and the PR gate's "build left nothing uncommitted" check never sees it.
|
|
23
45
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* neighbouring file. The directory carries its own `.gitignore` containing `*`, which ignores the
|
|
29
|
-
* directory and everything in it, so a consumer repo needs no gitignore edit and the PR gate's
|
|
30
|
-
* "build left nothing uncommitted" check never sees it.
|
|
46
|
+
* `architecture:visualize` scans every comparison that exists. `architecture:generate` refreshes
|
|
47
|
+
* ONLY the branch comparison (`GENERATE_IMPACT_KINDS`) and never scans the last commit; on main or a
|
|
48
|
+
* detached HEAD that leaves nothing to write, so it removes the sidecar and the page says to run
|
|
49
|
+
* `pnpm arch:visualize`.
|
|
31
50
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* Impact is a convenience. When nx or git cannot answer, NO sidecar is written (a stale one is
|
|
37
|
-
* removed) and the page disables Impact with a one-line reason. It never fails generation.
|
|
51
|
+
* Impact is a convenience. When nx or git cannot answer any comparison, NO sidecar is written (a
|
|
52
|
+
* stale one is removed) and the page disables Impact with a one-line reason. It never fails
|
|
53
|
+
* generation.
|
|
38
54
|
*/
|
|
39
55
|
import { DiffScope } from '@webpieces/rules-config';
|
|
40
56
|
import type { EnhancedGraph } from './graph-sorter';
|
|
@@ -42,10 +58,31 @@ import type { EnhancedGraph } from './graph-sorter';
|
|
|
42
58
|
export declare const IMPACT_SIDECAR_DIR = ".impact";
|
|
43
59
|
export declare const IMPACT_SIDECAR_FILE = "dependencies.impact.js";
|
|
44
60
|
export declare const IMPACT_SIDECAR_SRC = ".impact/dependencies.impact.js";
|
|
45
|
-
|
|
61
|
+
export declare const NOTHING_CHANGED_ON_BRANCH = "Nothing changed on this branch yet";
|
|
62
|
+
export declare const ROOT_COMMIT_REASON = "HEAD is the repository's first commit; there is no previous commit to compare against";
|
|
63
|
+
export declare const UNCOMMITTED_SUFFIX = " + uncommitted changes";
|
|
64
|
+
/** Which of the two comparisons a scan answers. */
|
|
65
|
+
export declare enum ImpactKind {
|
|
66
|
+
/** Fork point → working tree: "Changed on this branch". */
|
|
67
|
+
BRANCH = "branch",
|
|
68
|
+
/** HEAD^ → working tree: "Last commit". */
|
|
69
|
+
COMMIT = "commit"
|
|
70
|
+
}
|
|
71
|
+
/** `architecture:visualize` scans every comparison that exists. */
|
|
72
|
+
export declare const VISUALIZE_IMPACT_KINDS: readonly ImpactKind[];
|
|
73
|
+
/** `architecture:generate` refreshes the branch comparison only and never scans the last commit. */
|
|
74
|
+
export declare const GENERATE_IMPACT_KINDS: readonly ImpactKind[];
|
|
75
|
+
/** One scan as the sidecar carries it; the page reads `window.__WP_IMPACT__.scans`. */
|
|
46
76
|
export declare class ImpactReport {
|
|
77
|
+
readonly kind: ImpactKind;
|
|
78
|
+
/** What the page says this scan compares, e.g. "Changed on this branch (since abc1234)". */
|
|
79
|
+
readonly label: string;
|
|
80
|
+
/** The working tree had uncommitted or untracked changes (they count in the scan). */
|
|
81
|
+
readonly dirty: boolean;
|
|
47
82
|
readonly available: boolean;
|
|
83
|
+
/** Why the scan is unavailable; for an available but EMPTY scan, the note the page shows. */
|
|
48
84
|
readonly reason: string;
|
|
85
|
+
/** The base's short sha ('' when there is none). */
|
|
49
86
|
readonly base: string;
|
|
50
87
|
/** Affected AND owning a changed file (node ids). */
|
|
51
88
|
readonly touched: string[];
|
|
@@ -71,7 +108,15 @@ export declare class ImpactReport {
|
|
|
71
108
|
* legend names them. Empty when nx's file ownership was unavailable — then nothing is known.
|
|
72
109
|
*/
|
|
73
110
|
readonly globalFiles: string[];
|
|
74
|
-
constructor(
|
|
111
|
+
constructor(kind: ImpactKind,
|
|
112
|
+
/** What the page says this scan compares, e.g. "Changed on this branch (since abc1234)". */
|
|
113
|
+
label: string,
|
|
114
|
+
/** The working tree had uncommitted or untracked changes (they count in the scan). */
|
|
115
|
+
dirty: boolean, available: boolean,
|
|
116
|
+
/** Why the scan is unavailable; for an available but EMPTY scan, the note the page shows. */
|
|
117
|
+
reason: string,
|
|
118
|
+
/** The base's short sha ('' when there is none). */
|
|
119
|
+
base: string,
|
|
75
120
|
/** Affected AND owning a changed file (node ids). */
|
|
76
121
|
touched: string[],
|
|
77
122
|
/** Affected but owning no changed file (node ids): their ci re-runs. */
|
|
@@ -96,10 +141,67 @@ export declare class ImpactReport {
|
|
|
96
141
|
*/
|
|
97
142
|
globalFiles: string[]);
|
|
98
143
|
}
|
|
99
|
-
/**
|
|
144
|
+
/** The sidecar's one global: every scan, and the one the page shows first. */
|
|
145
|
+
export declare class ImpactSidecarData {
|
|
146
|
+
readonly scans: ImpactReport[];
|
|
147
|
+
readonly defaultKind: ImpactKind;
|
|
148
|
+
constructor(scans: ImpactReport[], defaultKind: ImpactKind);
|
|
149
|
+
}
|
|
150
|
+
/** A scan (or a whole plan) that could not produce an answer. */
|
|
100
151
|
export declare class ImpactUnavailable {
|
|
101
152
|
readonly reason: string;
|
|
102
|
-
|
|
153
|
+
readonly label: string;
|
|
154
|
+
constructor(reason: string, label?: string);
|
|
155
|
+
}
|
|
156
|
+
/** One comparison to scan. `base` is a full sha; null when it does not exist (`reason` says why). */
|
|
157
|
+
export declare class ImpactComparison {
|
|
158
|
+
readonly kind: ImpactKind;
|
|
159
|
+
readonly base: string | null;
|
|
160
|
+
readonly label: string;
|
|
161
|
+
readonly dirty: boolean;
|
|
162
|
+
readonly reason: string;
|
|
163
|
+
constructor(kind: ImpactKind, base: string | null, label: string, dirty: boolean, reason: string);
|
|
164
|
+
}
|
|
165
|
+
/** The comparisons that exist where HEAD is, and which one the page shows first. */
|
|
166
|
+
export declare class ImpactPlan {
|
|
167
|
+
readonly comparisons: ImpactComparison[];
|
|
168
|
+
readonly defaultKind: ImpactKind;
|
|
169
|
+
constructor(comparisons: ImpactComparison[], defaultKind: ImpactKind);
|
|
170
|
+
}
|
|
171
|
+
/** The few git facts the resolver needs. Injected so specs never spawn git. */
|
|
172
|
+
export declare class ImpactGit {
|
|
173
|
+
/** The checked-out branch's short name; null on a detached HEAD (or without git). */
|
|
174
|
+
branch(root: string): string | null;
|
|
175
|
+
/** The full sha `ref` names; null when it does not resolve (e.g. `HEAD^` on the first commit). */
|
|
176
|
+
sha(root: string, ref: string): string | null;
|
|
177
|
+
/** `git status --porcelain` is non-empty: uncommitted or untracked work. */
|
|
178
|
+
dirty(root: string): boolean;
|
|
179
|
+
/** HEAD's subject line ('' when unknown). */
|
|
180
|
+
subject(root: string): string;
|
|
181
|
+
/** Trimmed stdout, or null on any failure. */
|
|
182
|
+
private run;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Decides which comparisons exist from where HEAD is (#1163):
|
|
186
|
+
*
|
|
187
|
+
* | where | comparisons | default |
|
|
188
|
+
* |---|---|---|
|
|
189
|
+
* | `main` (by branch NAME) | last commit | last commit |
|
|
190
|
+
* | detached HEAD | last commit | last commit |
|
|
191
|
+
* | feature branch with commits past the fork point | branch, last commit | branch |
|
|
192
|
+
* | fresh feature branch (fork point = HEAD) | branch | branch |
|
|
193
|
+
*
|
|
194
|
+
* HEAD with no parent leaves the last commit unavailable, with `ROOT_COMMIT_REASON`.
|
|
195
|
+
*/
|
|
196
|
+
export declare class ImpactScopeResolver {
|
|
197
|
+
private readonly git;
|
|
198
|
+
private readonly diffScope;
|
|
199
|
+
constructor(git?: ImpactGit, diffScope?: DiffScope);
|
|
200
|
+
resolve(root: string): ImpactPlan | ImpactUnavailable;
|
|
201
|
+
private lastCommit;
|
|
202
|
+
/** detectBase may hand back a full or an abbreviated sha; compare on the shorter of the two. */
|
|
203
|
+
private sameCommit;
|
|
204
|
+
private short;
|
|
103
205
|
}
|
|
104
206
|
/** Runs the workspace's own nx CLI. Injected so specs never spawn nx. */
|
|
105
207
|
export declare class NxCli {
|
|
@@ -112,13 +214,32 @@ export declare class NxCli {
|
|
|
112
214
|
export declare class ProjectFileOwners {
|
|
113
215
|
owners(): Promise<Map<string, string>>;
|
|
114
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* nx's ownership map, computed at most ONCE however many comparisons ask for it. Failing is not
|
|
219
|
+
* fatal: the set then shows in one shade, all "affected".
|
|
220
|
+
*/
|
|
221
|
+
export declare class SharedOwners {
|
|
222
|
+
private readonly ownership;
|
|
223
|
+
private pending;
|
|
224
|
+
constructor(ownership: ProjectFileOwners);
|
|
225
|
+
get(): Promise<Map<string, string>>;
|
|
226
|
+
private load;
|
|
227
|
+
}
|
|
115
228
|
export declare class NxImpactScanner {
|
|
116
229
|
private readonly diffScope;
|
|
117
230
|
private readonly nx;
|
|
118
231
|
private readonly ownership;
|
|
119
232
|
private readonly names;
|
|
120
233
|
constructor(diffScope?: DiffScope, nx?: NxCli, ownership?: ProjectFileOwners);
|
|
121
|
-
|
|
234
|
+
/** Every comparison, in order, sharing one ownership map. */
|
|
235
|
+
scanAll(workspaceRoot: string, graph: EnhancedGraph, comparisons: ImpactComparison[]): Promise<(ImpactReport | ImpactUnavailable)[]>;
|
|
236
|
+
/** One comparison: nx affected from ITS base, with NO `--head`, so uncommitted work counts. */
|
|
237
|
+
scan(workspaceRoot: string, graph: EnhancedGraph, comparison: ImpactComparison, owners?: SharedOwners): Promise<ImpactReport | ImpactUnavailable>;
|
|
238
|
+
/**
|
|
239
|
+
* An empty scan is still an ANSWER (available, zero sets): a fresh branch with a clean tree has
|
|
240
|
+
* simply changed nothing yet, and the page says so instead of disabling Impact.
|
|
241
|
+
*/
|
|
242
|
+
emptyNote(comparison: ImpactComparison, changedFiles: number, short: string): string;
|
|
122
243
|
/** Changed files no project owns; none are claimed when ownership itself was unavailable. */
|
|
123
244
|
globalFiles(files: string[], owners: Map<string, string>): string[];
|
|
124
245
|
/**
|
|
@@ -131,23 +252,30 @@ export declare class NxImpactScanner {
|
|
|
131
252
|
touched(affected: string[], files: string[], owners: Map<string, string>): string[];
|
|
132
253
|
/** The JSON list, narrowed to projects the graph draws; null when it is not a list of names. */
|
|
133
254
|
parse(json: string, graph: EnhancedGraph): string[] | null;
|
|
134
|
-
|
|
135
|
-
private owners;
|
|
255
|
+
private report;
|
|
136
256
|
private ids;
|
|
137
257
|
}
|
|
138
258
|
/** Writes (or removes) the sidecar, self-ignored, beside architecture/dependencies.html. */
|
|
139
259
|
export declare class ImpactSidecar {
|
|
140
260
|
/** Never throws: a sidecar that cannot be written just leaves Impact disabled on the page. */
|
|
141
|
-
write(architectureDir: string,
|
|
142
|
-
/** A stale sidecar from an earlier
|
|
261
|
+
write(architectureDir: string, data: ImpactSidecarData): string | null;
|
|
262
|
+
/** A stale sidecar from an earlier checkout must never be shown as this one's impact. */
|
|
143
263
|
remove(architectureDir: string): void;
|
|
144
|
-
script(
|
|
264
|
+
script(data: ImpactSidecarData): string;
|
|
145
265
|
}
|
|
146
|
-
/** The
|
|
266
|
+
/** The executors' one call: resolve, scan each comparison, write, and report one line per comparison. */
|
|
147
267
|
export declare class ImpactRefresh {
|
|
148
268
|
private readonly scanner;
|
|
149
269
|
private readonly sidecar;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
270
|
+
private readonly resolver;
|
|
271
|
+
constructor(scanner?: NxImpactScanner, sidecar?: ImpactSidecar, resolver?: ImpactScopeResolver);
|
|
272
|
+
/**
|
|
273
|
+
* Scans the comparisons in `kinds` that exist here (`VISUALIZE_IMPACT_KINDS` /
|
|
274
|
+
* `GENERATE_IMPACT_KINDS`). Never throws — Impact is optional, generation is not.
|
|
275
|
+
*/
|
|
276
|
+
run(architectureDir: string, workspaceRoot: string, graph: EnhancedGraph, kinds: readonly ImpactKind[]): Promise<string>;
|
|
277
|
+
/** The plan's default when that scan is available, else the first available one. */
|
|
278
|
+
private defaultKind;
|
|
279
|
+
private none;
|
|
280
|
+
private line;
|
|
153
281
|
}
|