fix(manifest_ingest): read only a POM's own dependencies

_parse_pom collected every <dependency> in the file with
".//dependencies/dependency", including <dependencyManagement> entries,
which only pin versions, and the <dependencies> of build plugins. Each
became a depends_on edge, so a parent POM that manages its modules'
versions depended on every module.

Read <dependencies> under <project> and under <profiles><profile>, where
Maven takes a project's dependencies from.
This commit is contained in:
Jay Hemnani committed 2026-10-21 00:33:38 +05:30
1 parent b90b9df794
commit 534177d1ea
2 files changed
+27 -1

No files matched your search

+4 -1
View File
@@ -320,7 +320,10 @@ def _parse_pom(text: str) -> dict | None:
version = _resolve(version)
name = f"{gid}:{aid}" if gid else aid
deps: list[str] = []
for dep in root.findall(".//dependencies/dependency"):
# Only the project's own <dependencies> (and those of its profiles) are
# dependencies. <dependencyManagement> only pins versions, and a plugin's
# <dependencies> belong to the build tool.
for dep in root.findall("dependencies/dependency") + root.findall("profiles/profile/dependencies/dependency"):
da = _resolve(dep.findtext("artifactId"))
dg = _resolve(dep.findtext("groupId"))
if da:
+23
View File
@@ -75,6 +75,29 @@ def test_pom_parses_artifact_and_deps(tmp_path):
assert any(e["target"] == "pkg_org_lib_core" for e in r["edges"])
def test_pom_deps_exclude_managed_and_plugin_dependencies(tmp_path):
# <dependencyManagement> only pins versions and a plugin's <dependencies> are
# the build tool's; neither is a dependency of the project. Profile
# dependencies are.
dep = "<dependency><groupId>{}</groupId><artifactId>{}</artifactId></dependency>"
p = _write(tmp_path / "pom.xml",
'<project xmlns="http://maven.apache.org/POM/4.0.0">\n'
' <groupId>com.acme</groupId><artifactId>service</artifactId><version>1.0</version>\n'
f' <dependencyManagement><dependencies>{dep.format("com.google.guava", "guava")}'
'</dependencies></dependencyManagement>\n'
f' <dependencies>{dep.format("org.slf4j", "slf4j-api")}</dependencies>\n'
' <build><plugins><plugin><artifactId>maven-surefire-plugin</artifactId>\n'
f' <dependencies>{dep.format("org.junit.platform", "junit-platform-surefire-provider")}</dependencies>\n'
' </plugin></plugins></build>\n'
f' <profiles><profile><id>pg</id><dependencies>{dep.format("org.postgresql", "postgresql")}'
'</dependencies></profile></profiles>\n'
'</project>\n')
r = extract_package_manifest(p)
assert {e["target"] for e in r["edges"] if e["relation"] == "depends_on"} == {
"pkg_org_slf4j_slf4j_api", "pkg_org_postgresql_postgresql",
}
# ── #1377: a package referenced by N manifests is ONE node ───────────────────
def test_apm_dependency_collapses_to_single_canonical_node(tmp_path):