Skipping stage-native-deps on an admitted receipt kept a tree staged without a piece forever: get-windows (or its win32 x64 binding, which only the native installer inside staging can fetch), the macOS get-windows helper, or the host HUD helper (no X11 toolchain on Linux). The receipt identity cannot see the host fix that would complete it. The receipt now records `degraded` from the staged tree itself (nativeTreeComplete: every piece this host can produce for the target is present), and build.mjs reuses only a complete one (nativeInputsComplete). Gaps no host fix closes — win32-arm64 has no get-windows prebuild, a cross-target pack never builds the helpers — do not count. Judging the tree rather than each builder's return value covers soft-fail paths that still return a path (the win32 binding).
39 lines
2.1 KiB
JavaScript
39 lines
2.1 KiB
JavaScript
// npm's source-development composition; the compiler consumes prepared inputs.
|
|
import { execFileSync } from 'node:child_process'
|
|
import { cpSync } from 'node:fs'
|
|
import { join, resolve } from 'node:path'
|
|
import { parseArgs } from 'node:util'
|
|
import { isMain, repoRoot } from '../../../scripts/build/frontend-common.mjs'
|
|
import { nativeInputsComplete } from './prepared-native-deps.mjs'
|
|
|
|
export function buildSourceDesktop({ source = repoRoot, icons, run = execFileSync } = {}) {
|
|
source = resolve(source)
|
|
const app = join(source, 'apps/desktop')
|
|
const step = (script, args = []) => run(process.execPath, [join(source, script), ...args], { cwd: app, stdio: 'inherit' })
|
|
step('apps/desktop/scripts/assert-root-install.mjs')
|
|
// Stamp before the flavored icons land: they overwrite committed files, and
|
|
// the stamp's git check would then call the checkout dirty.
|
|
step('apps/desktop/scripts/write-build-stamp.mjs')
|
|
// Default-brand icons are committed; only flavored release builds pass --icons.
|
|
icons = resolve(icons ?? source)
|
|
if (icons !== source) {
|
|
// electron-builder consumes packaging artwork in the workspace. Copy the
|
|
// prepared pixels; do not create another Python environment to redraw them.
|
|
cpSync(join(icons, 'apps/desktop/assets'), join(app, 'assets'), { recursive: true })
|
|
}
|
|
// locales/_keys.desktop.json is a committed artifact (i18n-keys.test.mjs pins it to en.ts);
|
|
// the build must not write into the checkout — a dirty tree breaks `hermes update`.
|
|
// The native inputs carry their own receipt (inputs identity + tree digest): restaging the
|
|
// same sources recompiles two universal helpers for identical bytes on every update.
|
|
const nativeDeps = join(app, 'build/native-deps')
|
|
if (!nativeInputsComplete({ source, nativeDeps })) step('apps/desktop/scripts/stage-native-deps.mjs')
|
|
step('scripts/build/desktop.mjs', ['--source', source, '--icons', icons,
|
|
'--stamp', join(app, 'build/install-stamp.json'), '--native-deps', nativeDeps, '--out', join(app, 'dist')])
|
|
}
|
|
|
|
|
|
if (isMain(import.meta.url)) {
|
|
const { values } = parseArgs({ options: { icons: { type: 'string' } } })
|
|
buildSourceDesktop(values)
|
|
}
|