Skip to content

Commit 762bc89

Browse files
committed
Align reporter docs with reviewed behavior
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: d6318e80-5da9-4858-a147-817e8692f10e
1 parent 9ed2159 commit 762bc89

3 files changed

Lines changed: 143 additions & 35 deletions

File tree

apps/rush/src/test/sandbox/reporter-demo/README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ same-invocation JSON sidecar, final artifact completeness, owner-only log permis
1919
AI parser-error context, command-JSON ownership, exclusive sidecar destinations, and the
2020
`RUSH_REPORTER=legacy` rollback transcript. Inherited `RUSH_REPORTER`, `RUSH_LOG_LEVEL`, and
2121
`RUSH_QUIET_MODE` values are removed from the self-check matrix. It also verifies CI plaintext output,
22-
cache-path output, normalized `RUSH_TEMP_FOLDER` log placement, and matching purge-path selection.
23-
Captured stdout/stderr files are written to a temporary folder.
22+
cache-path output, a matching `RUSH_PREVIEW_VERSION`, normalized `RUSH_TEMP_FOLDER` log placement, and
23+
matching purge-path selection. Captured stdout/stderr files are written to a temporary folder.
24+
25+
The final matrix case invokes `rush purge` with an isolated `RUSH_TEMP_FOLDER`. This also unlinks project
26+
dependencies, so run the install command again before continuing development in the checkout.
2427

2528
For an individual invocation:
2629

@@ -30,8 +33,10 @@ node apps/rush/bin/rush build --only @rushstack/rush-reporter --reporter=default
3033

3134
node apps/rush/bin/rush build --only @rushstack/rush-reporter --reporter=plaintext
3235
node apps/rush/bin/rush build --only @rushstack/rush-reporter --reporter=json --log-level=debug
36+
RUSH_PREVIEW_VERSION=$(node -p "require('./apps/rush/package.json').version") node apps/rush/bin/rush build --only @rushstack/rush-reporter --reporter=json
3337
node apps/rush/bin/rush build --only @rushstack/rush-reporter --reporter=ai
3438
node apps/rush/bin/rush build --only @rushstack/rush-reporter --reporter=file
39+
RUSH_TEMP_FOLDER=./common/temp/reporter-demo-override node apps/rush/bin/rush build --only @rushstack/rush-reporter --reporter=file
3540
node apps/rush/bin/rush build --only @rushstack/rush-reporter --reporter=plaintext --log-level=quiet
3641
RUSH_REPORTER=legacy node apps/rush/bin/rush build --only @rushstack/rush-reporter --reporter=json
3742
node apps/rush/bin/rush list --json --reporter=file
@@ -47,8 +52,10 @@ The expected output is shape-based:
4752
- `default` uses a width-aware three-row live region and leaves a short final summary;
4853
- explicit `plaintext` groups ordered output under `project (phase)` and prints the absolute full-log path;
4954
- JSON stdout contains only NDJSON event envelopes;
55+
- a matching preview version keeps JSON stdout parseable and writes its warning to stderr;
5056
- AI stdout contains `ai.status` and bounded `ai.final` records;
5157
- file mode leaves stdout empty and writes the full-log path to stderr;
58+
- `RUSH_TEMP_FOLDER` moves the full log and the matching purge removes that override;
5259
- quiet mode retains only the final result and full-log path.
5360

5461
The intentional missing-project AI failure preserves an actionable diagnostic and complete log reference.

apps/rush/src/test/sandbox/reporter-demo/run.mjs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import { fileURLToPath } from 'node:url';
77
const scriptFolder = path.dirname(fileURLToPath(import.meta.url));
88
const repoRoot = path.resolve(scriptFolder, '..', '..', '..', '..', '..', '..');
99
const rushBin = path.join(repoRoot, 'apps', 'rush', 'bin', 'rush');
10+
const rushVersion = JSON.parse(
11+
fs.readFileSync(path.join(repoRoot, 'apps', 'rush', 'package.json'), 'utf8')
12+
).version;
1013
const outputFolder = fs.mkdtempSync(path.join(os.tmpdir(), 'rush-reporter-demo-'));
1114
const commonArgs = ['build', '--only', '@rushstack/rush-reporter'];
1215
const baseEnv = { ...process.env };
@@ -44,6 +47,9 @@ const plaintext = run('plaintext', [
4447
`--output=json://${plaintextEventsPath}?logLevel=debug`
4548
]).stdout;
4649
const json = run('json', [...commonArgs, '--reporter=json', '--log-level=debug']).stdout;
50+
const previewJson = run('preview-json', [...commonArgs, '--reporter=json'], {
51+
RUSH_PREVIEW_VERSION: rushVersion
52+
});
4753
const ai = run('ai', [...commonArgs, '--reporter=ai']).stdout;
4854
const file = run('file', [...commonArgs, '--reporter=file']);
4955
const quiet = run('quiet', [...commonArgs, '--reporter=plaintext', '--log-level=quiet']).stdout;
@@ -66,6 +72,18 @@ const flagOffHelp = run('help-flag-off', ['--help']).stdout;
6672
const help = run('help', ['--help', '--reporter=json'], { RUSH_REPORTER: 'legacy' }).stdout;
6773
const commandJson = run('command-json', ['list', '--json', '--reporter=file']);
6874
const commandJsonConflict = run('command-json-conflict', ['list', '--json', '--reporter=json'], {}, 1);
75+
const duplicateOutputPath = path.join(outputFolder, 'duplicate-output.jsonl');
76+
const outputConflict = run(
77+
'output-conflict',
78+
[
79+
...commonArgs,
80+
'--reporter=plaintext',
81+
`--output=json://${duplicateOutputPath}`,
82+
`--output=file://${duplicateOutputPath}`
83+
],
84+
{},
85+
1
86+
);
6987
const tempOverride = path.join(outputFolder, 'rush-temp-override');
7088
const tempOverrideFile = run('temp-override', [...commonArgs, '--reporter=file'], {
7189
RUSH_TEMP_FOLDER: tempOverride
@@ -86,18 +104,6 @@ const purgeLogMatch = tempPurge.stderr.match(/^Rush full log: (.+)$/m);
86104
if (!purgeLogMatch || purgeLogMatch[1].startsWith(tempOverride) || !fs.existsSync(purgeLogMatch[1])) {
87105
throw new Error('The active purge reporter log was not preserved outside RUSH_TEMP_FOLDER.');
88106
}
89-
const duplicateOutputPath = path.join(outputFolder, 'duplicate-output.jsonl');
90-
const outputConflict = run(
91-
'output-conflict',
92-
[
93-
...commonArgs,
94-
'--reporter=plaintext',
95-
`--output=json://${duplicateOutputPath}`,
96-
`--output=file://${duplicateOutputPath}`
97-
],
98-
{},
99-
1
100-
);
101107

102108
function parseNdjson(text, name) {
103109
if (text.includes('\u001b')) {
@@ -110,6 +116,7 @@ function parseNdjson(text, name) {
110116
}
111117

112118
const jsonEvents = parseNdjson(json, 'json');
119+
const previewJsonEvents = parseNdjson(previewJson.stdout, 'preview-json');
113120
const aiRecords = parseNdjson(ai, 'ai');
114121
const failureJsonEvents = parseNdjson(failureJson, 'failure-json');
115122
const failureAiRecords = parseNdjson(failureAi, 'failure-ai');
@@ -185,6 +192,12 @@ const aiFinal = aiRecords.at(-1);
185192
if (aiFinal?.kind !== 'ai.final' || aiFinal.log?.complete !== true) {
186193
throw new Error('AI output did not include a complete full-log reference.');
187194
}
195+
if (
196+
!previewJson.stderr.includes('RUSH_PREVIEW_VERSION') ||
197+
!previewJsonEvents.some((event) => event.type === 'sessionCompleted')
198+
) {
199+
throw new Error('The matching preview version did not preserve payload-only reporter stdout.');
200+
}
188201
const failureAiFinal = failureAiRecords.at(-1);
189202
if (
190203
failureAiFinal?.result !== 'failed' ||

0 commit comments

Comments
 (0)