Skip to content

--cargo only reads <scan-root>/Cargo.toml, so subdirectory manifests (Tauri's src-tauri/) yield no crate edges #3678

Description

@ExhibitJ

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:

  1. 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).
  2. 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.
  3. 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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions