From 3a4d78fc9f1f4fbd4ff0b9a07a5b6efc72c1ebc7 Mon Sep 17 00:00:00 2001 From: Victor Vogel Date: Sun, 8 Nov 2026 01:42:49 +0000 Subject: [PATCH 1/2] fix(scripts): report:renders starts on Windows without a vp shim runOnce spawned bare `vp`, which a shell-less spawn cannot resolve on Windows when the only vp is node_modules\.bin\vp.cmd, so the run failed with `exit null`. It now launches through vitePlusCommand, as check:changed does since #24164. Co-Authored-By: Claude Opus 5.5 --- scripts/render-metrics.test.ts | 10 ++++++++-- scripts/render-metrics.ts | 15 ++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/scripts/render-metrics.test.ts b/scripts/render-metrics.test.ts index 9ce66d27a9bde..251980efb1f95 100644 --- a/scripts/render-metrics.test.ts +++ b/scripts/render-metrics.test.ts @@ -5,16 +5,19 @@ import * as NodePath from "node:path"; import { describe, expect, it, vi } from "vite-plus/test"; +import { vitePlusCommand } from "./check-changed-command.ts"; import { nondeterministic, renderComparison, runOnce } from "./render-metrics.ts"; const mountReport = { commits: 2, renders: 10, components: { Row: 10 } }; +const spawned: Array<[command: string, args: string[]]> = []; vi.mock("node:child_process", () => ({ spawnSync: ( - _command: string, - _args: string[], + command: string, + args: string[], options: { env: { T3CODE_RENDER_REPORT_DIR: string } }, ) => { + spawned.push([command, args]); NodeFS.writeFileSync( NodePath.join(options.env.T3CODE_RENDER_REPORT_DIR, "mount.json"), JSON.stringify(mountReport), @@ -34,6 +37,9 @@ describe("runOnce", () => { try { expect(runOnce()).toEqual({ mount: mountReport }); expect(NodeFS.readdirSync(home)).toEqual([]); + spawned.length = 0; + runOnce("win32"); + expect(spawned).toEqual([vitePlusCommand(["test", "run", "--project", "renders"], "win32")]); } finally { vi.unstubAllEnvs(); NodeFS.rmSync(home, { recursive: true, force: true }); diff --git a/scripts/render-metrics.ts b/scripts/render-metrics.ts index 4c9a81c2d8994..a81ec5a779927 100644 --- a/scripts/render-metrics.ts +++ b/scripts/render-metrics.ts @@ -4,6 +4,8 @@ import * as NodeFS from "node:fs"; import * as NodeOS from "node:os"; import * as NodePath from "node:path"; +import { vitePlusCommand } from "./check-changed-command.ts"; + const HELP = `Usage: node scripts/render-metrics.ts run [--out ] [--runs ] node scripts/render-metrics.ts compare [--top ] @@ -37,10 +39,17 @@ export type RenderMetrics = Readonly>; const root = NodePath.resolve(import.meta.dirname, ".."); -export function runOnce(): RenderMetrics { +export function runOnce( + // oxlint-disable-next-line t3code/no-global-process-runtime -- Standalone Node tooling has no Effect runtime; tests pass the platform explicitly. + platform: NodeJS.Platform = process.platform, +): RenderMetrics { const directory = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-renders-")); try { - const result = NodeChildProcess.spawnSync("vp", ["test", "run", "--project", "renders"], { + const [command, commandArgs] = vitePlusCommand( + ["test", "run", "--project", "renders"], + platform, + ); + const result = NodeChildProcess.spawnSync(command, commandArgs, { cwd: NodePath.join(root, "apps/web"), env: { ...process.env, T3CODE_RENDER_REPORT_DIR: directory }, stdio: ["ignore", "inherit", "inherit"], @@ -119,7 +128,7 @@ if (import.meta.main) { const [command, ...args] = process.argv.slice(2); if (command === "run") { const runs = Number(option(args, "--runs") ?? 3); - const results = Array.from({ length: runs }, runOnce); + const results = Array.from({ length: runs }, () => runOnce()); const unstable = nondeterministic(results); if (unstable.length) { for (const scenario of unstable) { From 2da143093fcb4d4fb2bf9a212e0dfc6cdfade6e2 Mon Sep 17 00:00:00 2001 From: Victor Vogel Date: Sun, 8 Nov 2026 02:00:58 +0000 Subject: [PATCH 2/2] test(scripts): drop the render-metrics spawn mirror and the platform parameter it needed Co-Authored-By: Claude Opus 5.5 --- scripts/render-metrics.test.ts | 10 ++-------- scripts/render-metrics.ts | 12 +++--------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/scripts/render-metrics.test.ts b/scripts/render-metrics.test.ts index 251980efb1f95..9ce66d27a9bde 100644 --- a/scripts/render-metrics.test.ts +++ b/scripts/render-metrics.test.ts @@ -5,19 +5,16 @@ import * as NodePath from "node:path"; import { describe, expect, it, vi } from "vite-plus/test"; -import { vitePlusCommand } from "./check-changed-command.ts"; import { nondeterministic, renderComparison, runOnce } from "./render-metrics.ts"; const mountReport = { commits: 2, renders: 10, components: { Row: 10 } }; -const spawned: Array<[command: string, args: string[]]> = []; vi.mock("node:child_process", () => ({ spawnSync: ( - command: string, - args: string[], + _command: string, + _args: string[], options: { env: { T3CODE_RENDER_REPORT_DIR: string } }, ) => { - spawned.push([command, args]); NodeFS.writeFileSync( NodePath.join(options.env.T3CODE_RENDER_REPORT_DIR, "mount.json"), JSON.stringify(mountReport), @@ -37,9 +34,6 @@ describe("runOnce", () => { try { expect(runOnce()).toEqual({ mount: mountReport }); expect(NodeFS.readdirSync(home)).toEqual([]); - spawned.length = 0; - runOnce("win32"); - expect(spawned).toEqual([vitePlusCommand(["test", "run", "--project", "renders"], "win32")]); } finally { vi.unstubAllEnvs(); NodeFS.rmSync(home, { recursive: true, force: true }); diff --git a/scripts/render-metrics.ts b/scripts/render-metrics.ts index a81ec5a779927..97022db148bbf 100644 --- a/scripts/render-metrics.ts +++ b/scripts/render-metrics.ts @@ -39,16 +39,10 @@ export type RenderMetrics = Readonly>; const root = NodePath.resolve(import.meta.dirname, ".."); -export function runOnce( - // oxlint-disable-next-line t3code/no-global-process-runtime -- Standalone Node tooling has no Effect runtime; tests pass the platform explicitly. - platform: NodeJS.Platform = process.platform, -): RenderMetrics { +export function runOnce(): RenderMetrics { const directory = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-renders-")); try { - const [command, commandArgs] = vitePlusCommand( - ["test", "run", "--project", "renders"], - platform, - ); + const [command, commandArgs] = vitePlusCommand(["test", "run", "--project", "renders"]); const result = NodeChildProcess.spawnSync(command, commandArgs, { cwd: NodePath.join(root, "apps/web"), env: { ...process.env, T3CODE_RENDER_REPORT_DIR: directory }, @@ -128,7 +122,7 @@ if (import.meta.main) { const [command, ...args] = process.argv.slice(2); if (command === "run") { const runs = Number(option(args, "--runs") ?? 3); - const results = Array.from({ length: runs }, () => runOnce()); + const results = Array.from({ length: runs }, runOnce); const unstable = nondeterministic(results); if (unstable.length) { for (const scenario of unstable) {