Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions graphify/manifest_ingest.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ def extract_package_manifest(path: Path) -> dict[str, Any]:
except Exception as exc: # noqa: BLE001 — a malformed manifest must not abort extraction
return {"nodes": [], "edges": [], "error": f"manifest parse error: {exc}"}
if not info or not info.get("name"):
# A virtual workspace root (Cargo `[workspace]`, no `[package]`) is a
# legitimate zero-node result, not a failure (#1833): mark it
# "skipped" so extract.py's #1666 empty-source detector doesn't print
# a persistent "produced zero nodes" warning for a manifest that was
# never supposed to emit a package node. A manifest missing a name
# for any other reason keeps warning, since that IS unexplained.
if info and info.get("workspace_only"):
return {"nodes": [], "edges": [], "skipped": True}
return {"nodes": [], "edges": []}

name = info["name"]
Expand Down Expand Up @@ -237,6 +245,8 @@ def _parse_cargo(text: str) -> dict | None:
# package of its own — emit nothing rather than a fabricated node. ``name`` is
# never workspace-inheritable in Cargo, but guard on the type anyway.
if not isinstance(name, str) or not name:
if isinstance(data.get("workspace"), dict):
return {"name": None, "workspace_only": True, "deps": []}
return None
# ``version`` may be workspace-inherited (``version.workspace = true``), which
# parses to a table; keep only a concrete string version.
Expand Down
15 changes: 15 additions & 0 deletions tests/test_manifest_ingest.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,21 @@ def test_cargo_virtual_workspace_manifest_emits_no_package(tmp_path):
assert _pkg_nodes(r) == []


def test_cargo_virtual_workspace_manifest_is_marked_skipped(tmp_path):
# #1833: a virtual workspace root (no [package]) legitimately emits zero
# nodes by design. Without an explicit "skipped" marker, extract.py's
# #1666 empty-source detector treats this as an unexplained failure and
# prints a persistent "produced zero nodes" warning on every run. A
# manifest with no [workspace] table either (i.e. genuinely malformed,
# missing a name) must NOT be marked skipped — that would hide a real
# problem.
ws = _write(tmp_path / "ws" / "Cargo.toml", '[workspace]\nmembers = ["a"]\n')
assert extract_package_manifest(ws).get("skipped") is True

broken = _write(tmp_path / "broken" / "Cargo.toml", '[dependencies]\nserde = "1"\n')
assert extract_package_manifest(broken).get("skipped") is not True


def test_cargo_target_conditional_deps_are_collected(tmp_path):
# Platform-gated deps under [target.'cfg(...)'.dependencies] are common in
# real crates and must not be dropped just because they are conditional.
Expand Down