fix(desktop): tolerate omitted get-windows on ARM64
This commit is contained in:
+6
-7
@@ -1,12 +1,11 @@
|
||||
// Type declarations for the get-windows optionalDependency.
|
||||
//
|
||||
// get-windows ships no bundled types and is an optionalDependency: on Linux
|
||||
// `npm ci` skips it when its node-pre-gyp install script fails (no Linux
|
||||
// prebuilt; the node-gyp fallback needs `gyp` in the active Python), so the
|
||||
// package is legitimately absent from node_modules on Linux builds. Declaring
|
||||
// the module here keeps the typecheck independent of whether the package
|
||||
// installed — the runtime import in window-below.ts degrades to null when it
|
||||
// is absent.
|
||||
// get-windows ships no bundled types and is an optionalDependency. `npm ci`
|
||||
// can skip it when its native install fails, including Linux and Windows ARM64
|
||||
// where 9.3.0 has no prebuilt, so it can legitimately be absent from
|
||||
// node_modules. Declaring the module here keeps typecheck independent of
|
||||
// whether the package installed. The runtime import in window-below.ts
|
||||
// degrades to null when it is absent.
|
||||
|
||||
declare module 'get-windows' {
|
||||
export interface GetWindowsWindow {
|
||||
|
||||
@@ -125,11 +125,11 @@ type GetWindowsModule = {
|
||||
let getWindowsModule: Promise<GetWindowsModule | null> | null = null
|
||||
|
||||
const loadGetWindows = (): Promise<GetWindowsModule | null> => {
|
||||
// get-windows is an optionalDependency: on Linux `npm ci` skips it when its
|
||||
// node-pre-gyp install script fails (no Linux prebuilt, and the node-gyp
|
||||
// fallback needs `gyp` in the active Python). A missing module is therefore
|
||||
// a normal state, so the lazy import resolves to null instead of rejecting;
|
||||
// enumeration then degrades to the failure note instead of an uncaught error.
|
||||
// get-windows is an optionalDependency: `npm ci` can skip it when its native
|
||||
// install fails, including Linux and Windows ARM64 where 9.3.0 has no
|
||||
// prebuilt. A missing module is therefore a normal state on those targets,
|
||||
// so the lazy import resolves to null instead of rejecting; enumeration then
|
||||
// degrades to the failure note instead of an uncaught error.
|
||||
getWindowsModule ??= import('get-windows').catch(() => null)
|
||||
|
||||
return getWindowsModule
|
||||
|
||||
@@ -408,9 +408,9 @@ export function openWindowsSync() {
|
||||
|
||||
function resolveGetWindowsRoot() {
|
||||
// get-windows is an optionalDependency (its node-pre-gyp install script has
|
||||
// no Linux prebuilt and the node-gyp fallback needs `gyp` in the active
|
||||
// Python, so `npm ci` may skip it entirely on Linux). Return null when it is
|
||||
// absent; the caller decides whether that is fatal per platform.
|
||||
// no Linux or Windows ARM64 prebuilt and its node-gyp fallback may fail, so
|
||||
// `npm ci` can skip it entirely on those targets). Return null when it is
|
||||
// absent; the caller decides whether that is fatal per platform and arch.
|
||||
try {
|
||||
// get-windows' exports map doesn't expose ./package.json; resolve the entry
|
||||
// (index.js sits at the package root) and take its directory.
|
||||
@@ -565,22 +565,22 @@ export function stageGetWindows(
|
||||
const destRoot = resolve(projectRoot, 'dist/node_modules/get-windows')
|
||||
|
||||
if (!srcRoot) {
|
||||
// get-windows is an optionalDependency: `npm ci` on Linux skips it when the
|
||||
// install script fails (no Linux prebuilt, node-gyp needs `gyp` in the
|
||||
// active Python), so absence here is a normal state, not a broken checkout.
|
||||
// On Linux it only backs read_window_below over X11 (lib/linux.js shells
|
||||
// out to xprop); skipping it degrades that tool to Hyprland IPC or an
|
||||
// "unavailable" note instead of failing the whole desktop build. On
|
||||
// darwin/win32 the native payload is required, so fail loudly.
|
||||
if (platform === 'linux') {
|
||||
// npm may omit an optional dependency whose install script fails. That is
|
||||
// expected on Linux and win32-arm64 because get-windows 9.3.0 publishes no
|
||||
// native prebuilt for either target. The runtime import already fails soft,
|
||||
// so disable only window enumeration instead of failing the Desktop build.
|
||||
// Other Windows architectures and macOS have supported native payloads and
|
||||
// remain fail-closed so a broken package cannot ship silently.
|
||||
const canDegrade = platform === 'linux' || (platform === 'win32' && arch === 'arm64')
|
||||
if (canDegrade) {
|
||||
console.warn(
|
||||
'[stage-native-deps] get-windows not installed (optional dep skipped on ' +
|
||||
'Linux); read_window_below will be unavailable in this build'
|
||||
`[stage-native-deps] get-windows not installed (optional dep skipped for ${platform}-${arch}); ` +
|
||||
'read_window_below will be unavailable in this build'
|
||||
)
|
||||
return undefined
|
||||
}
|
||||
throw new Error(
|
||||
`[stage-native-deps] get-windows is not installed; cannot stage its ${platform} native payload`
|
||||
`[stage-native-deps] get-windows is not installed; cannot stage its ${platform}-${arch} native payload`
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -551,10 +551,10 @@ test('darwin staging ships the Swift helper executable and the rewritten windows
|
||||
// ─── stageGetWindows (optionalDependency gate) ──────────────────────
|
||||
//
|
||||
// get-windows is an optionalDependency: on Linux its node-pre-gyp install
|
||||
// script fails (no Linux prebuilt; the node-gyp fallback needs `gyp` in the
|
||||
// active Python), so npm skips the package and `npm ci` must still succeed.
|
||||
// The staging step mirrors that: absent package on Linux is a skip, on
|
||||
// darwin/win32 it is a hard failure because the native payload is required.
|
||||
// script fails because no prebuilt exists. Windows ARM64 has the same package
|
||||
// state: its prebuilt URL returns 404 and npm may omit the optional dependency.
|
||||
// Staging skips those unsupported targets, but supported native targets remain
|
||||
// a hard failure when the package is missing.
|
||||
|
||||
test('linux staging skips when get-windows is absent (optional dep skipped by npm)', () => {
|
||||
assert.equal(stageGetWindows({ platform: 'linux', resolveRoot: () => null }), undefined)
|
||||
@@ -562,14 +562,21 @@ test('linux staging skips when get-windows is absent (optional dep skipped by np
|
||||
|
||||
test('darwin staging fails when get-windows is absent', () => {
|
||||
assert.throws(
|
||||
() => stageGetWindows({ platform: 'darwin', resolveRoot: () => null }),
|
||||
() => stageGetWindows({ platform: 'darwin', arch: 'arm64', resolveRoot: () => null }),
|
||||
/get-windows is not installed/
|
||||
)
|
||||
})
|
||||
|
||||
test('win32 staging fails when get-windows is absent', () => {
|
||||
test('win32-arm64 staging skips when get-windows is absent after its optional install fails', () => {
|
||||
assert.equal(
|
||||
stageGetWindows({ platform: 'win32', arch: 'arm64', resolveRoot: () => null }),
|
||||
undefined
|
||||
)
|
||||
})
|
||||
|
||||
test('win32-x64 staging fails when get-windows is absent', () => {
|
||||
assert.throws(
|
||||
() => stageGetWindows({ platform: 'win32', resolveRoot: () => null }),
|
||||
() => stageGetWindows({ platform: 'win32', arch: 'x64', resolveRoot: () => null }),
|
||||
/get-windows is not installed/
|
||||
)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user