fix(desktop): resolve electronDist to the actual electron install location (#48081)
After the June lockfile regeneration (#46652) floated electron and reshuffled npm workspace hoisting, the desktop pack fails with "The specified electronDist does not exist". apps/desktop/package.json pointed electronDist at the repo root (../../node_modules/electron/dist) while npm now installs electron nested under apps/desktop/node_modules/electron. The two contradict, so a clean install can never package the app (Windows + macOS). - electronDist -> node_modules/electron/dist (resolved relative to apps/desktop, i.e. the workspace-local install npm actually produces). - hermes_cli/main.py, scripts/install.sh, scripts/install.ps1: add a runtime electron-dir resolver that prefers apps/desktop/node_modules/electron and falls back to the root hoist, so dist checks + the mirror re-download work under either npm layout. - patch-electron-builder-mac-binary.cjs: try the workspace-local Electron.app before the root hoist in the macOS binary-restore fallback (sibling site no PR touched). - test: assert build.electronDist resolves to where the lockfile installs electron, so a future hoist change (root <-> nested) can't silently break it. Salvages the overlapping work in #48003 (sitkarev), #48012 (omegazheng), and #48033 (james47kjv). Co-authored-by: sitkarev <59806492+sitkarev@users.noreply.github.com> Co-authored-by: omegazheng <zheng@omegasys.eu> Co-authored-by: james47kjv <220877172+james47kjv@users.noreply.github.com>
This commit is contained in:
co-authored by
sitkarev
omegazheng
james47kjv
parent
016bce1a09
commit
f8098c6b6f
@@ -616,6 +616,33 @@ def test_electron_dist_ok_per_platform(tmp_path, monkeypatch, platform, rel):
|
||||
assert cli_main._electron_dist_ok(tmp_path) is True
|
||||
|
||||
|
||||
def test_electron_dir_prefers_workspace_local_package(tmp_path):
|
||||
"""npm may nest electron under apps/desktop; resolve there over the root hoist."""
|
||||
root_electron = tmp_path / "node_modules" / "electron"
|
||||
local_electron = tmp_path / "apps" / "desktop" / "node_modules" / "electron"
|
||||
root_electron.mkdir(parents=True)
|
||||
local_electron.mkdir(parents=True)
|
||||
|
||||
assert cli_main._electron_dir(tmp_path) == local_electron
|
||||
|
||||
|
||||
def test_electron_dir_falls_back_to_root_hoist(tmp_path):
|
||||
"""When npm hoists electron to the repo root, resolve there."""
|
||||
root_electron = tmp_path / "node_modules" / "electron"
|
||||
root_electron.mkdir(parents=True)
|
||||
|
||||
assert cli_main._electron_dir(tmp_path) == root_electron
|
||||
|
||||
|
||||
def test_electron_dist_ok_finds_workspace_local_binary(tmp_path, monkeypatch):
|
||||
"""A nested apps/desktop electron with a valid binary counts as ok."""
|
||||
monkeypatch.setattr(cli_main.sys, "platform", "linux")
|
||||
binp = tmp_path / "apps" / "desktop" / "node_modules" / "electron" / "dist" / "electron"
|
||||
binp.parent.mkdir(parents=True)
|
||||
binp.write_text("", encoding="utf-8")
|
||||
assert cli_main._electron_dist_ok(tmp_path) is True
|
||||
|
||||
|
||||
def test_redownload_electron_dist_noop_when_present(tmp_path, monkeypatch):
|
||||
"""Already-healthy dist → no download, so an unrelated build failure can't
|
||||
trigger a needless ~200 MB refetch."""
|
||||
|
||||
@@ -94,3 +94,42 @@ def test_lockfile_resolves_the_pinned_electron():
|
||||
f"but the pin is {spec!r}; run `npm install --package-lock-only` so "
|
||||
"`npm ci` stays consistent."
|
||||
)
|
||||
|
||||
|
||||
def test_electron_dist_matches_lockfile_install_location():
|
||||
"""build.electronDist must point at where the lockfile installs Electron.
|
||||
|
||||
electron-builder copies the unpacked Electron from ``build.electronDist``
|
||||
(resolved relative to ``apps/desktop``). npm workspace hoisting is not
|
||||
deterministic across machines/npm versions: it may nest Electron under
|
||||
``apps/desktop/node_modules/electron`` or hoist it to the repo root. If
|
||||
electronDist points at one location while the lockfile installs at the
|
||||
other, packaging fails with ``The specified electronDist does not exist`` —
|
||||
the "Building desktop app" failure reported after the June lockfile
|
||||
regeneration floated Electron and reshuffled the hoist. Lock the two
|
||||
together so a hoist change (root <-> nested) can't silently break the path
|
||||
again.
|
||||
"""
|
||||
if not ROOT_LOCK.is_file():
|
||||
pytest.skip("root package-lock.json not present")
|
||||
electron_dist = _desktop_pkg().get("build", {}).get("electronDist")
|
||||
assert electron_dist, "build.electronDist is missing"
|
||||
|
||||
lock = json.loads(ROOT_LOCK.read_text(encoding="utf-8"))
|
||||
electron_paths = [
|
||||
path
|
||||
for path in lock.get("packages", {})
|
||||
if path.endswith("node_modules/electron")
|
||||
]
|
||||
assert electron_paths, "no electron entry found in package-lock.json"
|
||||
|
||||
desktop_dir = REPO_ROOT / "apps" / "desktop"
|
||||
# electronDist is resolved relative to the apps/desktop project dir.
|
||||
configured = (desktop_dir / electron_dist).resolve()
|
||||
# Where the lockfile actually places Electron's unpacked dist.
|
||||
installed = {(REPO_ROOT / p / "dist").resolve() for p in electron_paths}
|
||||
assert configured in installed, (
|
||||
f"build.electronDist={electron_dist!r} resolves to {configured}, but the "
|
||||
f"lockfile installs Electron at {sorted(str(p) for p in installed)}. "
|
||||
"electron-builder will fail with 'electronDist does not exist'."
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user