in doc-architect/doc-architect-core/src/main/java/com/docarchitect/core/scanner/impl/python/PipPoetryDependencyScanner.java [305:392]
private void parsePyprojectToml(Path file, String sourceComponentId, List<Dependency> dependencies) throws IOException {
String content = readFileContent(file);
JsonNode root = tomlMapper.readTree(content);
// Parse [project.dependencies] (PEP 621)
JsonNode project = root.get(CONFIG_KEY_PROJECT);
if (project != null) {
JsonNode deps = project.get(CONFIG_KEY_DEPENDENCIES);
if (deps != null && deps.isArray()) {
for (JsonNode dep : deps) {
parseDependencySpec(dep.asText(), sourceComponentId, SCOPE_COMPILE, dependencies);
}
}
// Parse [project.optional-dependencies] (PEP 621)
JsonNode optionalDeps = project.get(CONFIG_KEY_OPTIONAL_DEPENDENCIES);
if (optionalDeps != null && optionalDeps.isObject()) {
optionalDeps.fields().forEachRemaining(entry -> {
if (entry.getValue().isArray()) {
for (JsonNode dep : entry.getValue()) {
parseDependencySpec(dep.asText(), sourceComponentId, SCOPE_OPTIONAL, dependencies);
}
}
});
}
}
// Parse [dependency-groups] (PEP 735) - used by uv, Hatch, and modern Python tools
JsonNode dependencyGroups = root.get(CONFIG_KEY_DEPENDENCY_GROUPS);
if (dependencyGroups != null && dependencyGroups.isObject()) {
dependencyGroups.fields().forEachRemaining(entry -> {
String groupName = entry.getKey();
String scope = groupName.equals("dev") || groupName.equals("test") ? SCOPE_TEST : SCOPE_OPTIONAL;
if (entry.getValue().isArray()) {
for (JsonNode dep : entry.getValue()) {
parseDependencySpec(dep.asText(), sourceComponentId, scope, dependencies);
}
}
});
}
// Parse [tool.poetry.dependencies] (Poetry format)
JsonNode tool = root.get(CONFIG_KEY_TOOL);
if (tool != null) {
JsonNode poetry = tool.get(CONFIG_KEY_POETRY);
if (poetry != null) {
JsonNode poetryDeps = poetry.get(CONFIG_KEY_DEPENDENCIES);
if (poetryDeps != null && poetryDeps.isObject()) {
poetryDeps.fields().forEachRemaining(entry -> {
String packageName = entry.getKey();
if (!POETRY_PYTHON_KEY.equals(packageName)) {
String version = extractVersionFromPoetryDep(entry.getValue());
Dependency dep = new Dependency(
sourceComponentId,
PYPI_GROUP_ID,
packageName,
version,
SCOPE_COMPILE,
true
);
dependencies.add(dep);
}
});
}
// Parse [tool.poetry.dev-dependencies]
JsonNode devDeps = poetry.get(CONFIG_KEY_DEV_DEPENDENCIES);
if (devDeps != null && devDeps.isObject()) {
devDeps.fields().forEachRemaining(entry -> {
String packageName = entry.getKey();
String version = extractVersionFromPoetryDep(entry.getValue());
Dependency dep = new Dependency(
sourceComponentId,
PYPI_GROUP_ID,
packageName,
version,
SCOPE_TEST,
true
);
dependencies.add(dep);
});
}
}
}
log.debug("Parsed pyproject.toml: {}", file);
}