Files
OpenJarvis/tests/deployment/test_packaging.py
T
26bc7efb09 fix(packaging): make openjarvis-rust a uv-only group to unblock pip install openjarvis[desktop] (#624)
* fix(packaging): make openjarvis-rust a uv-only dependency group (unblock pip[desktop])

#615 added openjarvis-rust to the published `desktop` extra so
`uv sync --extra desktop` builds the native PyO3 extension for the desktop
app. But openjarvis-rust is not on PyPI and `[tool.uv.sources]` is stripped
from published wheel metadata, so `pip install openjarvis[desktop]` from PyPI
failed at install trying to resolve openjarvis-rust from PyPI (#584).

Move openjarvis-rust into a uv `desktop-native` dependency group (PEP 735 —
excluded from wheel metadata) and sync it in the desktop app via
`uv sync --group desktop-native`. The extension is still built from the local
path source; only the published metadata changes.

Verified: the built wheel no longer lists openjarvis-rust in any Requires-Dist
(nowhere in the metadata), and uv.lock still resolves it from the local path
source under the group. Adds tests/deployment/test_packaging.py to guard the
split (not in the published extra, present in the group, path source, and the
desktop app syncs the group).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(packaging): sync native group in install paths

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Elliot Slusky <elliot@slusky.com>
2026-07-01 13:02:13 -07:00

62 lines
2.3 KiB
Python

"""Guards for the openjarvis-rust packaging split (#584 / #615).
``openjarvis_rust`` is the native PyO3 extension. It is NOT published to PyPI,
so it must not appear in the published ``desktop`` extra — listing it there
breaks ``pip install openjarvis[desktop]`` at install time. It lives in the uv
``desktop-native`` dependency group instead (excluded from wheel metadata),
which the desktop app installs from source via
``uv sync --group desktop-native``.
"""
from __future__ import annotations
from pathlib import Path
import tomllib
ROOT = Path(__file__).resolve().parent.parent.parent
PYPROJECT = ROOT / "pyproject.toml"
DESKTOP_LIB_RS = ROOT / "frontend" / "src-tauri" / "src" / "lib.rs"
WINDOWS_INSTALL_PS1 = ROOT / "deploy" / "windows" / "install.ps1"
def _pyproject() -> dict:
return tomllib.loads(PYPROJECT.read_text())
def test_openjarvis_rust_not_in_published_desktop_extra() -> None:
desktop = _pyproject()["project"]["optional-dependencies"]["desktop"]
assert not any("openjarvis-rust" in dep for dep in desktop), (
"openjarvis-rust must not be in the published `desktop` extra — it is "
"not on PyPI, so it breaks `pip install openjarvis[desktop]`."
)
def test_openjarvis_rust_lives_in_uv_dependency_group() -> None:
group = _pyproject()["dependency-groups"]["desktop-native"]
assert any("openjarvis-rust" in dep for dep in group)
def test_openjarvis_rust_has_local_uv_path_source() -> None:
src = _pyproject()["tool"]["uv"]["sources"]["openjarvis-rust"]
assert src["path"] == "rust/crates/openjarvis-python"
def test_desktop_app_syncs_the_native_group() -> None:
# Otherwise the group's openjarvis_rust is never installed for the app.
assert '"desktop-native"' in DESKTOP_LIB_RS.read_text(), (
"the desktop app must `uv sync --group desktop-native` so the native "
"extension is built at launch."
)
def test_windows_installer_syncs_the_native_group() -> None:
# The Windows source installer does not run maturin separately.
assert (
"& $uvExe sync --extra desktop --group desktop-native"
in WINDOWS_INSTALL_PS1.read_text()
), (
"the Windows installer must include `--group desktop-native` so "
"openjarvis_rust is built during source install."
)