@flighthq/tool-capture 0.4.0-next.1585.bf131c8 → 0.4.0-next.1602.af48ed1
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.
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
export declare const CAPTURE_BUILD_IDENTITY_FILE = "capture-build.json";
|
|
2
2
|
export declare const MAX_CAPTURE_BUILD_DIRTY_PATHS = 50;
|
|
3
|
+
/**
|
|
4
|
+
* Paths whose dirtiness cannot reach a render, and are therefore not evidence about the build.
|
|
5
|
+
*
|
|
6
|
+
* ★ THE QUESTION THE DIRTY LIST ANSWERS IS "COULD WHAT I CAPTURED DIFFER FROM THE COMMITTED TREE". A
|
|
7
|
+
* file that no build step reads and no scene imports cannot change a pixel, so listing it does not
|
|
8
|
+
* answer that question — it just adds noise to the answer.
|
|
9
|
+
*
|
|
10
|
+
* ★ THESE TWO ARE THE REVIEW WORKFLOW'S OWN OUTPUT, WHICH MAKES THE NOISE SELF-INFLICTED AND RECURRING.
|
|
11
|
+
* Commissioning writes a request into `reference-image-requests/` and holding writes
|
|
12
|
+
* `scripts/reference-image-held.json`; both are then uncommitted, so the NEXT review of the same session
|
|
13
|
+
* reports "Built with uncommitted changes" and names files the reviewer just created by reviewing. A
|
|
14
|
+
* warning that fires because you used the tool teaches you to ignore the warning, which is the one
|
|
15
|
+
* outcome worse than not having it — and it fires on exactly the iterative loop the tool exists for.
|
|
16
|
+
*
|
|
17
|
+
* ★ ADDING TO THIS LIST IS A CLAIM, NOT A CONVENIENCE. The claim is that nothing under the prefix is read
|
|
18
|
+
* by a build step or a scene. `functional/baselines/` deliberately stays OUT: a changed baseline does not
|
|
19
|
+
* alter a render, but it does alter what a capture reports as changed, so its dirtiness is evidence about
|
|
20
|
+
* the run even though it is not evidence about the build.
|
|
21
|
+
*/
|
|
22
|
+
export declare const CAPTURE_BUILD_DIRTY_EXEMPT_PREFIXES: readonly string[];
|
|
3
23
|
export interface CaptureBuildIdentity {
|
|
4
24
|
/** The commit checked out when the build began. */
|
|
5
25
|
commit: string | null;
|
|
@@ -12,6 +32,8 @@ export declare const UNSTAMPED_CAPTURE_BUILD: CaptureBuildIdentity;
|
|
|
12
32
|
export declare function createCaptureBuildIdentity(commit: string | null, allDirtyPaths: readonly string[]): CaptureBuildIdentity;
|
|
13
33
|
/** Reads git once at build time and creates the record that is stamped into dist. */
|
|
14
34
|
export declare function getCaptureBuildIdentity(repositoryRoot: string): CaptureBuildIdentity;
|
|
35
|
+
/** Whether a dirty path is one the build and the scenes provably never read. */
|
|
36
|
+
export declare function isCaptureBuildDirtyExempt(path: string): boolean;
|
|
15
37
|
/** Paths from `git status --porcelain=v1 -z`; rename/copy pairs remain one readable entry. */
|
|
16
38
|
export declare function parseGitStatusPaths(status: string): string[];
|
|
17
39
|
/** Reads a build-owned stamp from the directory capture is actually serving. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"captureBuildIdentity.d.ts","sourceRoot":"","sources":["../src/captureBuildIdentity.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,2BAA2B,uBAAuB,CAAC;AAChE,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAEhD,MAAM,WAAW,oBAAoB;IACnC,mDAAmD;IACnD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,0FAA0F;IAC1F,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,gGAAgG;IAChG,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,uBAAuB,EAAE,oBAAmE,CAAC;AAE1G,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,oBAAoB,
|
|
1
|
+
{"version":3,"file":"captureBuildIdentity.d.ts","sourceRoot":"","sources":["../src/captureBuildIdentity.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,2BAA2B,uBAAuB,CAAC;AAChE,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAEhD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,mCAAmC,EAAE,SAAS,MAAM,EAGhE,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,mDAAmD;IACnD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,0FAA0F;IAC1F,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,gGAAgG;IAChG,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,uBAAuB,EAAE,oBAAmE,CAAC;AAE1G,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,oBAAoB,CAOtB;AAED,qFAAqF;AACrF,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,MAAM,GAAG,oBAAoB,CAepF;AAED,gFAAgF;AAChF,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAO/D;AAED,8FAA8F;AAC9F,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAgB5D;AAED,gFAAgF;AAChF,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAqBvF"}
|
|
@@ -7,12 +7,36 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
export const CAPTURE_BUILD_IDENTITY_FILE = 'capture-build.json';
|
|
9
9
|
export const MAX_CAPTURE_BUILD_DIRTY_PATHS = 50;
|
|
10
|
+
/**
|
|
11
|
+
* Paths whose dirtiness cannot reach a render, and are therefore not evidence about the build.
|
|
12
|
+
*
|
|
13
|
+
* ★ THE QUESTION THE DIRTY LIST ANSWERS IS "COULD WHAT I CAPTURED DIFFER FROM THE COMMITTED TREE". A
|
|
14
|
+
* file that no build step reads and no scene imports cannot change a pixel, so listing it does not
|
|
15
|
+
* answer that question — it just adds noise to the answer.
|
|
16
|
+
*
|
|
17
|
+
* ★ THESE TWO ARE THE REVIEW WORKFLOW'S OWN OUTPUT, WHICH MAKES THE NOISE SELF-INFLICTED AND RECURRING.
|
|
18
|
+
* Commissioning writes a request into `reference-image-requests/` and holding writes
|
|
19
|
+
* `scripts/reference-image-held.json`; both are then uncommitted, so the NEXT review of the same session
|
|
20
|
+
* reports "Built with uncommitted changes" and names files the reviewer just created by reviewing. A
|
|
21
|
+
* warning that fires because you used the tool teaches you to ignore the warning, which is the one
|
|
22
|
+
* outcome worse than not having it — and it fires on exactly the iterative loop the tool exists for.
|
|
23
|
+
*
|
|
24
|
+
* ★ ADDING TO THIS LIST IS A CLAIM, NOT A CONVENIENCE. The claim is that nothing under the prefix is read
|
|
25
|
+
* by a build step or a scene. `functional/baselines/` deliberately stays OUT: a changed baseline does not
|
|
26
|
+
* alter a render, but it does alter what a capture reports as changed, so its dirtiness is evidence about
|
|
27
|
+
* the run even though it is not evidence about the build.
|
|
28
|
+
*/
|
|
29
|
+
export const CAPTURE_BUILD_DIRTY_EXEMPT_PREFIXES = [
|
|
30
|
+
'reference-image-requests/',
|
|
31
|
+
'scripts/reference-image-held.json',
|
|
32
|
+
];
|
|
10
33
|
export const UNSTAMPED_CAPTURE_BUILD = { commit: null, dirty: [], dirtyOmitted: 0 };
|
|
11
34
|
export function createCaptureBuildIdentity(commit, allDirtyPaths) {
|
|
35
|
+
const relevant = allDirtyPaths.filter((path) => !isCaptureBuildDirtyExempt(path));
|
|
12
36
|
return {
|
|
13
37
|
commit,
|
|
14
|
-
dirty:
|
|
15
|
-
dirtyOmitted: Math.max(0,
|
|
38
|
+
dirty: relevant.slice(0, MAX_CAPTURE_BUILD_DIRTY_PATHS),
|
|
39
|
+
dirtyOmitted: Math.max(0, relevant.length - MAX_CAPTURE_BUILD_DIRTY_PATHS),
|
|
16
40
|
};
|
|
17
41
|
}
|
|
18
42
|
/** Reads git once at build time and creates the record that is stamped into dist. */
|
|
@@ -33,6 +57,13 @@ export function getCaptureBuildIdentity(repositoryRoot) {
|
|
|
33
57
|
return UNSTAMPED_CAPTURE_BUILD;
|
|
34
58
|
}
|
|
35
59
|
}
|
|
60
|
+
/** Whether a dirty path is one the build and the scenes provably never read. */
|
|
61
|
+
export function isCaptureBuildDirtyExempt(path) {
|
|
62
|
+
// A rename record is `old -> new`; either side landing under an exempt prefix is still the same class
|
|
63
|
+
// of file, and the pair is only formatted for a human to read.
|
|
64
|
+
const candidates = path.includes(' -> ') ? path.split(' -> ') : [path];
|
|
65
|
+
return candidates.every((candidate) => CAPTURE_BUILD_DIRTY_EXEMPT_PREFIXES.some((prefix) => candidate.startsWith(prefix)));
|
|
66
|
+
}
|
|
36
67
|
/** Paths from `git status --porcelain=v1 -z`; rename/copy pairs remain one readable entry. */
|
|
37
68
|
export function parseGitStatusPaths(status) {
|
|
38
69
|
const records = status.split('\0');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"captureBuildIdentity.js","sourceRoot":"","sources":["../src/captureBuildIdentity.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,oGAAoG;AACpG,oGAAoG;AACpG,iDAAiD;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,2BAA2B,GAAG,oBAAoB,CAAC;AAChE,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"captureBuildIdentity.js","sourceRoot":"","sources":["../src/captureBuildIdentity.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/tool-capture",
|
|
3
|
-
"version": "0.4.0-next.
|
|
3
|
+
"version": "0.4.0-next.1602.af48ed1",
|
|
4
4
|
"author": "Joshua Granick and other contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -42,11 +42,11 @@
|
|
|
42
42
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@flighthq/capture": "0.4.0-next.
|
|
46
|
-
"@flighthq/effects-wgpu": "0.4.0-next.
|
|
47
|
-
"@flighthq/render-wgpu": "0.4.0-next.
|
|
48
|
-
"@flighthq/bitmap": "0.4.0-next.
|
|
49
|
-
"@flighthq/types": "0.4.0-next.
|
|
45
|
+
"@flighthq/capture": "0.4.0-next.1602.af48ed1",
|
|
46
|
+
"@flighthq/effects-wgpu": "0.4.0-next.1602.af48ed1",
|
|
47
|
+
"@flighthq/render-wgpu": "0.4.0-next.1602.af48ed1",
|
|
48
|
+
"@flighthq/bitmap": "0.4.0-next.1602.af48ed1",
|
|
49
|
+
"@flighthq/types": "0.4.0-next.1602.af48ed1",
|
|
50
50
|
"@playwright/test": "^1.50.0",
|
|
51
51
|
"picocolors": "^1.1.1"
|
|
52
52
|
},
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
CAPTURE_BUILD_IDENTITY_FILE,
|
|
10
10
|
createCaptureBuildIdentity,
|
|
11
11
|
getCaptureBuildIdentity,
|
|
12
|
+
isCaptureBuildDirtyExempt,
|
|
12
13
|
parseGitStatusPaths,
|
|
13
14
|
readCaptureBuildIdentity,
|
|
14
15
|
} from './captureBuildIdentity';
|
|
@@ -22,6 +23,42 @@ describe('createCaptureBuildIdentity', () => {
|
|
|
22
23
|
expect(build.dirty).toEqual(paths.slice(0, 50));
|
|
23
24
|
expect(build.dirtyOmitted).toBe(5);
|
|
24
25
|
});
|
|
26
|
+
|
|
27
|
+
// ★ THE REVIEW WORKFLOW'S OWN OUTPUT IS NOT EVIDENCE ABOUT THE BUILD. Commissioning writes a request
|
|
28
|
+
// file and holding writes the ledger; both are then uncommitted, so the next review in the same session
|
|
29
|
+
// warned "Built with uncommitted changes" and named files the reviewer had just created BY REVIEWING.
|
|
30
|
+
// A warning that fires because you used the tool is one people learn to ignore.
|
|
31
|
+
it('ignores the request queue and the hold ledger, which no build step reads', () => {
|
|
32
|
+
const build = createCaptureBuildIdentity('a'.repeat(40), [
|
|
33
|
+
'reference-image-requests/09cb2e5b.json',
|
|
34
|
+
'scripts/reference-image-held.json',
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
expect(build.dirty).toEqual([]);
|
|
38
|
+
expect(build.dirtyOmitted).toBe(0);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// The exemption must not swallow the signal it sits next to: a real source edit alongside a request file
|
|
42
|
+
// is still a dirty build, and the warning still has to say so.
|
|
43
|
+
it('still reports a source path dirtied in the same tree', () => {
|
|
44
|
+
const build = createCaptureBuildIdentity('a'.repeat(40), [
|
|
45
|
+
'reference-image-requests/09cb2e5b.json',
|
|
46
|
+
'functional/scenes/text-basic.ts',
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
expect(build.dirty).toEqual(['functional/scenes/text-basic.ts']);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// The omitted count is taken AFTER the exemption, or a queue of fifty stale requests would report fifty
|
|
53
|
+
// omissions and re-create the noise the exemption removes.
|
|
54
|
+
it('counts omissions after the exemption, not before', () => {
|
|
55
|
+
const requests = Array.from({ length: 60 }, (_, index) => `reference-image-requests/r${index}.json`);
|
|
56
|
+
|
|
57
|
+
const build = createCaptureBuildIdentity('a'.repeat(40), [...requests, 'packages/bitmap/src/bitmap.ts']);
|
|
58
|
+
|
|
59
|
+
expect(build.dirty).toEqual(['packages/bitmap/src/bitmap.ts']);
|
|
60
|
+
expect(build.dirtyOmitted).toBe(0);
|
|
61
|
+
});
|
|
25
62
|
});
|
|
26
63
|
|
|
27
64
|
describe('getCaptureBuildIdentity', () => {
|
|
@@ -51,6 +88,31 @@ describe('getCaptureBuildIdentity', () => {
|
|
|
51
88
|
});
|
|
52
89
|
});
|
|
53
90
|
|
|
91
|
+
describe('isCaptureBuildDirtyExempt', () => {
|
|
92
|
+
it('exempts a path under the request queue', () => {
|
|
93
|
+
expect(isCaptureBuildDirtyExempt('reference-image-requests/09cb2e5b.json')).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('does not exempt a scene or a package source', () => {
|
|
97
|
+
expect(isCaptureBuildDirtyExempt('functional/scenes/text-basic.ts')).toBe(false);
|
|
98
|
+
expect(isCaptureBuildDirtyExempt('packages/bitmap/src/bitmap.ts')).toBe(false);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// ★ `functional/baselines/` IS DELIBERATELY NOT EXEMPT, and the distinction is the whole rule. A changed
|
|
102
|
+
// baseline alters no render, but it does alter what a capture reports as CHANGED — so its dirtiness is
|
|
103
|
+
// evidence about the run even though it is not evidence about the build.
|
|
104
|
+
it('does not exempt a committed baseline', () => {
|
|
105
|
+
expect(isCaptureBuildDirtyExempt('functional/baselines/text-basic.json')).toBe(false);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// A rename is one readable record with both sides; exempting it requires both sides to be exempt, so a
|
|
109
|
+
// file moved OUT of the queue into the tree still counts as dirty.
|
|
110
|
+
it('exempts a rename only when both sides are exempt', () => {
|
|
111
|
+
expect(isCaptureBuildDirtyExempt('reference-image-requests/a.json -> reference-image-requests/b.json')).toBe(true);
|
|
112
|
+
expect(isCaptureBuildDirtyExempt('reference-image-requests/a.json -> functional/scenes/a.ts')).toBe(false);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
54
116
|
describe('parseGitStatusPaths', () => {
|
|
55
117
|
it('keeps porcelain paths literal and represents a rename as one dirty entry', () => {
|
|
56
118
|
expect(parseGitStatusPaths(' M ordinary.ts\0?? path with spaces.ts\0R renamed.ts\0old.ts\0')).toEqual([
|