Skip to content

fix(ingest): recognize Cargo.toml as a package manifest (#2434) - #2494

Open
ousamabenyounes wants to merge 1 commit into
Graphify-Labs:v8from
ousamabenyounes:fix/issue-2434
Open

fix(ingest): recognize Cargo.toml as a package manifest (#2434)#2494
ousamabenyounes wants to merge 1 commit into
Graphify-Labs:v8from
ousamabenyounes:fix/issue-2434

Conversation

@ousamabenyounes

Copy link
Copy Markdown

What

Recognize Rust's Cargo.toml as a package manifest, alongside the
pyproject.toml / go.mod / pom.xml that manifest_ingest already handles.

Fix #2434 (scoped to the issue's Request 1 — "Add Cargo.toml to
PACKAGE_MANIFEST_NAMES", which the issue calls out as "a one-line fix
independent of the rest of this issue"). Requests 2 and 3 (routing
.toml/.ini/.cfg into DOC_EXTENSIONS, and a generic structural TOML
extractor) are deliberately left out — they are broader, separate concerns.

Why

PACKAGE_MANIFEST_NAMES maps Python's, Go's, Maven's and apm's manifests to a
deterministic parser that emits one canonical package node per package (plus
depends_on edges). Rust's Cargo.toml was missing, so a Rust repo got no
package node where an otherwise-identical Python repo did — the gap the issue
documents.

How

  • Add "cargo.toml": "cargo" to PACKAGE_MANIFEST_NAMES and a matching
    _parse_cargo in _PARSERS (both must move together — a name without a
    parser would route the file to a KeyError path).
  • _parse_cargo mirrors _parse_pyproject: name/version from [package],
    runtime deps from [dependencies] and every [target.<cfg>.dependencies]
    table (platform-conditional deps are common in real crates). It reuses the
    shared _coerce_deps / _pkg_id helpers, so an inline-table dep
    (tokio = { version = "1", features = [...] }) keys by the dependency name.
  • Defensive, matching the sibling parsers: a virtual workspace root (no
    [package]) emits nothing rather than a fabricated node, and a
    workspace-inherited version (version.workspace = true, which parses to a
    table) is dropped instead of crashing.
  • dev-dependencies / build-dependencies are intentionally excluded to match
    _parse_pyproject's runtime-only scope.
  • Doc-sync: updated the module docstring and the classify_file comment, and
    added a CHANGELOG.md entry under 0.9.34 (unreleased).

Test verification (RED → GREEN)

Five new tests in tests/test_manifest_ingest.py.

RED — new tests against unmodified v8 (before the fix), production code stashed:

graphify/manifest_ingest.py:60: KeyError: 'cargo.toml'
FAILED tests/test_manifest_ingest.py::test_cargo_classifies_as_code_manifest
FAILED tests/test_manifest_ingest.py::test_cargo_parses_name_version_and_deps
FAILED tests/test_manifest_ingest.py::test_cargo_virtual_workspace_manifest_emits_no_package
FAILED tests/test_manifest_ingest.py::test_cargo_target_conditional_deps_are_collected
FAILED tests/test_manifest_ingest.py::test_cargo_workspace_inherited_version_does_not_crash
5 failed, 8 deselected

GREEN — with the fix:

tests/test_manifest_ingest.py: 12 passed

Full local CI (mirrors .github/workflows/ci.yml)

uv run --frozen ruff check graphify tests        -> All checks passed!
uv run --frozen python -m tools.skillgen --check -> check OK: 134 artifact(s) match
uv run --frozen pytest tests/ -q                 -> 4049 passed, 3 skipped
uv run --frozen graphify --help                  -> OK

Baseline on v8 before the change was 4044 passed, 3 skipped; the delta is
exactly the 5 new tests, no regressions. New production lines are fully covered
by the new tests.

…s#2434)

Cargo.toml was absent from PACKAGE_MANIFEST_NAMES, so a Rust crate got no
canonical package node while pyproject.toml / go.mod / pom.xml all did. Add a
'cargo' ecosystem entry plus a deterministic _parse_cargo that reads name and
version from [package] and dependency edges from [dependencies] and every
[target.<cfg>.dependencies] table, mirroring _parse_pyproject's runtime-only
scope. Virtual-workspace roots (no [package]) and workspace-inherited versions
emit no fabricated node and do not crash.

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).

Graphify reviewed this change.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).


Graphify review — findings

This PR adds Cargo.toml to the set of package manifests that graphify parses deterministically (alongside apm.yml, pyproject.toml, go.mod, and pom.xml). It introduces a _parse_cargo function that extracts the package name/version from [package] and dependencies from [dependencies] and [target.<cfg>.dependencies] tables, registers it in the manifest name map and parser dispatch, and routes Cargo.toml to the CODE classification path. It also updates the changelog and doc comments, and adds tests covering classification, dep parsing, virtual workspaces, target-conditional deps, and workspace-inherited versions.

No blocking issues surfaced. 1 lower-confidence candidate did not survive cross-model review.

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 1337 functions depend on the 310 functions this change touches.

Health — this change adds coupling hotspots:

  • worse: classify_file() — 43 callers, 3 callees

Verification — 1337 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 978 function(s) in the blast radius were not formally verified this run

· 1 grounded finding(s) anchored inline below.

Comment thread graphify/detect.py
@@ -488,7 +488,7 @@ def _shebang_file_type(path: Path) -> FileType | None:


def classify_file(path: Path) -> FileType | None:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Health regressionclassify_file()

43 callers depend on it (afferent coupling).

Grounded coupling-delta finding (deterministic), not an LLM guess.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.toml is in no extension set, so config/data TOML is never collected — not even as a document

1 participant