fix(cli): set PYTHON env for node-gyp native builds on NixOS (#40690)

* fix(cli): set PYTHON env for node-gyp native builds on NixOS

node-gyp (triggered by node-pty during npm ci) looks for python3 on
PATH, which fails on NixOS because python3 lives in the nix store and
is not on the system PATH.

Add _nixos_build_env() — a two-tier helper that detects NixOS and:
1. Fast path: hermes venv python3 (~0s)
2. Fallback: nix-shell which python3 (~2-5s)

Wire it into _run_npm_install_deterministic() via a new env= parameter,
then pass it through cmd_gui() and _update_node_dependencies().

Non-NixOS systems: _nixos_build_env() returns None, behavior unchanged.

* fix(cli): merge _nixos_build_env() with os.environ, fix NixOS detection, add explicit return None

- Critical fix: both Tier 1 (venv) and Tier 2 (nix-shell) now return
  {**os.environ, "PYTHON": ...} instead of {"PYTHON": ...} — subprocess.run
  with env= replaces the entire environment, so the old code wiped PATH
  and broke npm/node on NixOS entirely.
- Uses re.search(r"^ID=nixos$", ...) for anchored NixOS detection instead
  of unanchored substring match (could match ID_LIKE=...nixos).
- Removes redundant Path.exists() guard before read_text(); just catches
  OSError (one filesystem read instead of two).
- Adds explicit return None at end of function for type-hint consistency.
This commit is contained in:
floory
2026-06-08 13:57:37 +05:30
committed by GitHub
parent 7a5827c8b0
commit 15c99b437f
2 changed files with 63 additions and 2 deletions
+1 -1
View File
@@ -70,7 +70,7 @@ def test_gui_installs_packages_and_launches_desktop_app(tmp_path, monkeypatch):
cli_main.cmd_gui(_ns())
assert exc.value.code == 0
mock_install.assert_called_once_with("/usr/bin/npm", root, capture_output=False)
mock_install.assert_called_once_with("/usr/bin/npm", root, capture_output=False, env=None)
assert mock_run.call_args_list[0].args[0] == ["/usr/bin/npm", "run", "pack"]
assert mock_run.call_args_list[0].kwargs["cwd"] == desktop_dir
assert mock_run.call_args_list[1].args[0] == [str(packaged_exe)]