LogFlames commented on PR #50: URL: https://github.com/apache/maven-dependency-tree/pull/50#issuecomment-2531073528
I will add tests 👍 This PR would be a prerequisite for https://issues.apache.org/jira/browse/MDEP-962. Currently if running `mvn dependency:tree -Dverbose=true` it outputs: ``` [INFO] --- dependency:3.6.1:tree (default-cli) @ attackvector --- [INFO] org.evil:attackvector:jar:1.2 [INFO] +- junit:junit:jar:4.11:test [INFO] | \- org.hamcrest:hamcrest-core:jar:1.3:test [INFO] +- org.postgresql:postgresql:jar:42.6.0:compile [INFO] | \- (org.checkerframework:checker-qual:jar:3.31.0:runtime - omitted for duplicate) [INFO] +- org.springframework:spring-jdbc:jar:5.3.27:compile [INFO] | +- org.springframework:spring-beans:jar:5.3.27:compile [INFO] | | \- (org.springframework:spring-core:jar:5.3.27:compile - omitted for duplicate) [INFO] | +- org.springframework:spring-core:jar:5.3.27:compile [INFO] | | \- org.springframework:spring-jcl:jar:5.3.27:compile [INFO] | \- org.springframework:spring-tx:jar:5.3.27:compile [INFO] | +- (org.springframework:spring-beans:jar:5.3.27:compile - omitted for duplicate) [INFO] | \- (org.springframework:spring-core:jar:5.3.27:compile - omitted for duplicate) [...] ``` This includes dependencies which were omitted in parenthesis and information such as `omitted for duplicate`, etc The corresponding JSON output (`mvn dependency:tree -Dverbose=true -DoutputType=json`) looks like this: ```json --- dependency:3.7.0:tree (default-cli) @ attackvector --- [INFO] { [INFO] "groupId": "org.evil", [INFO] "artifactId": "attackvector", [INFO] "version": "1.2", [INFO] "type": "jar", [INFO] "scope": "", [INFO] "classifier": "", [INFO] "optional": "false", [INFO] "children": [ [INFO] { [INFO] "groupId": "junit", [INFO] "artifactId": "junit", [INFO] "version": "4.11", [INFO] "type": "jar", [INFO] "scope": "test", [INFO] "classifier": "", [INFO] "optional": "false", [INFO] "children": [ [INFO] { [INFO] "groupId": "org.hamcrest", [INFO] "artifactId": "hamcrest-core", [INFO] "version": "1.3", [INFO] "type": "jar", [INFO] "scope": "test", [INFO] "classifier": "", [INFO] "optional": "false" [INFO] } [INFO] ] [INFO] }, [INFO] { [INFO] "groupId": "org.postgresql", [INFO] "artifactId": "postgresql", [INFO] "version": "42.6.0", [INFO] "type": "jar", [INFO] "scope": "compile", [INFO] "classifier": "", [INFO] "optional": "false", [INFO] "children": [ [INFO] { [INFO] "groupId": "org.checkerframework", [INFO] "artifactId": "checker-qual", [INFO] "version": "3.31.0", [INFO] "type": "jar", [INFO] "scope": "runtime", [INFO] "classifier": "", [INFO] "optional": "false" [INFO] } [INFO] ] [INFO] }, [INFO] { [INFO] "groupId": "org.springframework", [INFO] "artifactId": "spring-jdbc", [INFO] "version": "5.3.27", [INFO] "type": "jar", [INFO] "scope": "compile", [INFO] "classifier": "", [INFO] "optional": "false", [INFO] "children": [ [INFO] { [INFO] "groupId": "org.springframework", [INFO] "artifactId": "spring-beans", [INFO] "version": "5.3.27", [INFO] "type": "jar", [INFO] "scope": "compile", [INFO] "classifier": "", [INFO] "optional": "false", [INFO] "children": [ [INFO] { [INFO] "groupId": "org.springframework", [INFO] "artifactId": "spring-core", [INFO] "version": "5.3.27", [INFO] "type": "jar", [INFO] "scope": "compile", [INFO] "classifier": "", [INFO] "optional": "false" [INFO] } [INFO] ] [INFO] }, [INFO] { [INFO] "groupId": "org.springframework", [INFO] "artifactId": "spring-core", [INFO] "version": "5.3.27", [INFO] "type": "jar", [INFO] "scope": "compile", [INFO] "classifier": "", [INFO] "optional": "false", [INFO] "children": [ [INFO] { [INFO] "groupId": "org.springframework", [INFO] "artifactId": "spring-jcl", [INFO] "version": "5.3.27", [INFO] "type": "jar", [INFO] "scope": "compile", [INFO] "classifier": "", [INFO] "optional": "false" [INFO] } [INFO] ] [INFO] }, [INFO] { [INFO] "groupId": "org.springframework", [INFO] "artifactId": "spring-tx", [INFO] "version": "5.3.27", [INFO] "type": "jar", [INFO] "scope": "compile", [INFO] "classifier": "", [INFO] "optional": "false", [INFO] "children": [ [INFO] { [INFO] "groupId": "org.springframework", [INFO] "artifactId": "spring-beans", [INFO] "version": "5.3.27", [INFO] "type": "jar", [INFO] "scope": "compile", [INFO] "classifier": "", [INFO] "optional": "false" [INFO] }, [INFO] { [INFO] "groupId": "org.springframework", [INFO] "artifactId": "spring-core", [INFO] "version": "5.3.27", [INFO] "type": "jar", [INFO] "scope": "compile", [INFO] "classifier": "", [INFO] "optional": "false" [INFO] } [INFO] ] [INFO] } [INFO] ] [INFO] }, [...] ``` The argument `-Dverbose=true` causes maven-dependency-tree it to return VerboseDependencyNodes instead of DefaultDependencyNodes, but important information such as which are omitted, is missing. This is however currently not exposed from the VerboseDependencyNode as these are internal, other than the function toNodeString, where the formatting with parethesis and omitted reason are included. My goal with this change would be to construct more useful JSON programmatically, where more key-value pairs could be added: `"included": true/false, "omitted_reason": ...`, without having to parse the toNodeString for example. It would allow the JSON to be constructed with (https://github.com/apache/maven-dependency-plugin/blob/ae19d893bb61a4b8414877721ca25b580c454dad/src/main/java/org/apache/maven/plugins/dependency/tree/JsonDependencyNodeVisitor.java#L123) ```java /** * Appends the artifact values to the string builder. * * @param sb the string builder to append to * @param indent the current indent level * @param artifact the artifact to write * @param hasChildren true if the artifact has children */ - private void appendNodeValues(StringBuilder sb, int indent, Artifact artifact, boolean hasChildren) { + private void appendNodeValues(StringBuilder sb, int indent, Artifact artifact, DependencyNode node, boolean hasChildren) { appendKeyValue(sb, indent, "groupId", artifact.getGroupId()); appendKeyValue(sb, indent, "artifactId", artifact.getArtifactId()); appendKeyValue(sb, indent, "version", artifact.getVersion()); appendKeyValue(sb, indent, "type", artifact.getType()); appendKeyValue(sb, indent, "scope", artifact.getScope()); appendKeyValue(sb, indent, "classifier", artifact.getClassifier()); + if (node.getGetConflictData() != null) { + ConflictData conflictData = node.getGetConflictData(); + appendKeyValue(sb, indent, "included", conflictData.getWinnerVersion() == null); + if (conflictData.getOriginalVersion() != null) { + appendKeyValue(sb, indent, "version_updated_from", conflictData.getOriginalVersion()); + } + if (conflictData.getIgnoredScope() != null) { + appendKeyValue(sb, indent, "scope_not_updated_to", conflictData.getIgnoredScope()); + } + } [...] ``` Using the resolver API directly would be a nice way to solve this as well, as ConflictData is a subset of the DependencyNode.getData(), which seems to be what the resolver API works with. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@maven.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org