d753957e8a
* fix(install): time-box the Windows node-deps stage so a stalled npm or Playwright install can't hang setup forever scripts/install.sh has bounded this same work with run_with_timeout "$NODE_DEPS_TIMEOUT" (600s default) since #39219, but install.ps1 never got the guard: Install-NodeDeps ran both `npm install` and `npx playwright install chromium` unbounded. A stalled registry fetch or a wedged Chromium archive extraction (#76222, #84614) froze the installer indefinitely -- one user left it running 12+ hours overnight before asking for help. Route both invocations through _Invoke-NativeWithTimeout: cmd.exe launches the native command with its output merged to a log, the parent polls with a wall-clock deadline and tails new log lines to the console each tick (the live progress that makes a 3-minute download distinguishable from a hang), and on timeout taskkill /T /F kills the real process tree and returns 124 -- the same convention as coreutils timeout and bash's run_with_timeout. Wait-Job was rejected for this: jobs swallow live output and Stop-Job leaves the npm child running. Windows PowerShell 5.1-safe throughout. Timeouts surface as a warning with the log path, a note that re-running the installer resumes (stages are idempotent), and the NODE_DEPS_TIMEOUT env override for slow links -- mirroring bash. Fixes #76222. Closes #84614. Supersedes #76303. Co-authored-by: JonthanaHanh <JonthanaHanh@users.noreply.github.com> * fix(installer): roll stage timers over to hours so an overnight stall doesn't read as "744 hours" formatElapsed rendered a running stage as m:ss with unbounded minutes: a node-deps stage left hanging overnight showed "744:38", which the user who reported the hang understandably read as 744 hours. formatDuration (completed stages) had the same unbounded-minutes shape. Move both formatters into src/lib/format.ts (pure, no React) and add the hour rollover: h:mm:ss live, "Xh Ym" completed. tests-js pins the shapes, including 744m38s -> 12:24:38. --------- Co-authored-by: JonthanaHanh <JonthanaHanh@users.noreply.github.com>
36 lines
1.2 KiB
TypeScript
36 lines
1.2 KiB
TypeScript
/*
|
|
* Duration formatters for the stage list. Pure functions, no React — kept out
|
|
* of progress.tsx so tests-js can exercise them without dragging in the Tauri
|
|
* renderer.
|
|
*/
|
|
|
|
// Duration of a completed stage: ms, then s, then "Xm Ys", then "Xh Ym".
|
|
export function formatDuration(ms: number): string {
|
|
if (ms < 1000) {return `${ms}ms`}
|
|
|
|
if (ms < 60000) {return `${(ms / 1000).toFixed(1)}s`}
|
|
const m = Math.floor(ms / 60000)
|
|
const s = Math.round((ms % 60000) / 1000)
|
|
|
|
if (m < 60) {return `${m}m ${s}s`}
|
|
const h = Math.floor(m / 60)
|
|
|
|
return `${h}h ${m - h * 60}m`
|
|
}
|
|
|
|
// Live elapsed for a running stage: bare seconds under a minute, then m:ss,
|
|
// then h:mm:ss past an hour. Without the hour rollover a stalled overnight
|
|
// stage read as "744:38" — minutes rendered unbounded — which one user
|
|
// understandably reported as "744 hours".
|
|
export function formatElapsed(ms: number): string {
|
|
const s = Math.max(0, Math.floor(ms / 1000))
|
|
|
|
if (s < 60) {return `${s}s`}
|
|
const m = Math.floor(s / 60)
|
|
|
|
if (m < 60) {return `${m}:${String(s - m * 60).padStart(2, '0')}`}
|
|
const h = Math.floor(m / 60)
|
|
|
|
return `${h}:${String(m - h * 60).padStart(2, '0')}:${String(s % 60).padStart(2, '0')}`
|
|
}
|