Summary
--cargo only ever looks for a manifest at <scan-root>/Cargo.toml. There is no discovery — no walk, no glob, no fallback — so any repository whose Rust crate lives in a subdirectory gets no crate nodes or crate→crate dependency edges, even though the AST pass has already parsed every .rs file in that subdirectory.
The most common instance is a Tauri app: Tauri's default scaffold puts Cargo.toml in src-tauri/, so --cargo never finds it on any stock Tauri project. The same applies to other polyglot layouts (rust/, crates/, backend/, native/) where the repository root is a JS/Python project and Rust is one component.
Mechanism
cargo_introspect.py:
def introspect_cargo(root: str | Path) -> dict[str, Any]:
"""Return crate nodes and internal dependency edges from Cargo manifests."""
root_path = Path(root).resolve()
root_manifest = root_path / "Cargo.toml"
root_data = _load_toml(root_manifest)
manifests = _member_manifest_paths(root_path, root_data)
_member_manifest_paths does handle workspace members via workspace.members globs — but only once the root manifest has been loaded. If the root manifest does not exist, nothing downstream runs.
Why the location is already known
By the time --cargo runs, the AST pass has parsed every Rust file in the repository, so the crate's location is available from the extraction results. In the run below, 95 .rs files under src-tauri/ were parsed successfully, and src-tauri/Cargo.toml sits beside them:
$ graphify extract . --code-only
[graphify extract] found 441 code, 0 docs, 0 papers, 0 images
[graphify extract] wrote graphify-out/graph.json: 5005 nodes, 12371 edges, 214 communities
$ ls Cargo.toml
ls: Cargo.toml: No such file or directory
$ ls src-tauri/Cargo.toml
src-tauri/Cargo.toml
Suggested fix
Any of these would resolve it, roughly in increasing order of effort:
- Search for
Cargo.toml at the scan root, then one or two levels down, taking the first match (or all matches, treating each as an independent crate root).
- Derive candidate manifest directories from the parsed Rust sources — the parent directories of
.rs files already in the extraction — and check each for a manifest.
- Accept an explicit path, e.g.
--cargo <path-to-Cargo.toml>, with the current behavior as the default.
Note that with the current code, a missing root manifest does not merely skip the cargo pass — it aborts the entire extraction and discards the completed AST work. That is filed separately as a distinct defect.
Environment
graphify 0.9.64 · macOS 22.6.0 · Python 3.12 · installed via uv tool install graphifyy
Summary
--cargoonly ever looks for a manifest at<scan-root>/Cargo.toml. There is no discovery — no walk, no glob, no fallback — so any repository whose Rust crate lives in a subdirectory gets no crate nodes or crate→crate dependency edges, even though the AST pass has already parsed every.rsfile in that subdirectory.The most common instance is a Tauri app: Tauri's default scaffold puts
Cargo.tomlinsrc-tauri/, so--cargonever finds it on any stock Tauri project. The same applies to other polyglot layouts (rust/,crates/,backend/,native/) where the repository root is a JS/Python project and Rust is one component.Mechanism
cargo_introspect.py:_member_manifest_pathsdoes handle workspace members viaworkspace.membersglobs — but only once the root manifest has been loaded. If the root manifest does not exist, nothing downstream runs.Why the location is already known
By the time
--cargoruns, the AST pass has parsed every Rust file in the repository, so the crate's location is available from the extraction results. In the run below, 95.rsfiles undersrc-tauri/were parsed successfully, andsrc-tauri/Cargo.tomlsits beside them:Suggested fix
Any of these would resolve it, roughly in increasing order of effort:
Cargo.tomlat the scan root, then one or two levels down, taking the first match (or all matches, treating each as an independent crate root)..rsfiles already in the extraction — and check each for a manifest.--cargo <path-to-Cargo.toml>, with the current behavior as the default.Note that with the current code, a missing root manifest does not merely skip the cargo pass — it aborts the entire extraction and discards the completed AST work. That is filed separately as a distinct defect.
Environment
graphify 0.9.64 · macOS 22.6.0 · Python 3.12 · installed via
uv tool install graphifyy