Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MDEP-799] tree: add optional output type json #325

Closed
wants to merge 4 commits into from

Conversation

MartinWitt
Copy link
Contributor

@MartinWitt MartinWitt commented May 22, 2023

Following this checklist to help us incorporate your
contribution quickly and easily:

  • Make sure there is a JIRA issue filed
    for the change (usually before you start working on it). Trivial changes like typos do not
    require a JIRA issue. Your pull request should address just this issue, without
    pulling in other changes.
  • Each commit in the pull request should have a meaningful subject line and body.

I will squash and update the commit in the end. There is still open discussion.

  • Format the pull request title like [MDEP-XXX] - Fixes bug in ApproximateQuantiles,
    where you replace MDEP-XXX with the appropriate JIRA issue. Best practice
    is to use the JIRA issue title in the pull request title and in the first line of the
    commit message.

  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.

  • Run mvn clean verify to make sure basic checks pass. A more thorough check will
    be performed on your pull request automatically.

  • You have run the integration tests successfully (mvn -Prun-its clean verify).

  • I hereby declare this contribution to be licensed under the Apache License Version 2.0, January 2004

  • In any other case, please file an Apache Individual Contributor License Agreement.

I sent the mail for this a few minutes ago so it should be signed soon.

I tried to understand the way you write unit/integration tests but it looks a bit complicated. What is the correct way to add a testcase? Best case, I can add a pom and check if the model written as json -> read by any JSON parser is equal to the model before.

The JSON files currently exist for you to see the current printed format. It will be deleted afterward.

This PR adds JSON output type to the maven-depdenceny-plugin with the goal tree.

Supersedes #207

@MartinWitt MartinWitt changed the title WIP: [MDEP-799] tree: add optional output type json [MDEP-799] tree: add optional output type json May 22, 2023
@MartinWitt
Copy link
Contributor Author

CLA is now signed and accepted.

@MartinWitt
Copy link
Contributor Author

As I am a first-time contributor, someone has to approve the workflow run before we see CI results.

@MartinWitt
Copy link
Contributor Author

@elharo could you approve the worflow run?

}

@Override
public boolean visit(DependencyNode node) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible for this to et stuck in an infinite recursion with a maliciously hand-crafted dependency node? Or for that matter, with a non-maliciious but buggy circular dependency tree (which does happen)?

Choose a reason for hiding this comment

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

@elharo the cure may be to keep track of already visited nodes and either fail or keep trucking?

Copy link
Contributor

Choose a reason for hiding this comment

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

add a test for this case, see what works

*/
public class JsonDependencyNodeVisitor extends AbstractSerializingVisitor implements DependencyNodeVisitor {

private static final String LINE_SEPARATOR = "\n";
Copy link
Contributor

Choose a reason for hiding this comment

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

inline this, a simple "\n" is clearer

}
}
/**
* Appends the node and it's children to the string builder.
Copy link
Contributor

Choose a reason for hiding this comment

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

its

* @param key the key used as json key
* @param value the value used as json value
*/
private void appendKey(StringBuilder sb, int indent, String key, String value) {
Copy link
Contributor

Choose a reason for hiding this comment

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

appendKeyValue

*/
public void _testTreeJsonSerialzing() throws Exception {
List<String> contents = runTreeMojo("tree1.json", "json");
assertTrue(findString(contents, "\"testGroupId\": \"project\""));
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure why findString is used here. contains is simple and more obvious

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to keep the test case in the same style as the rest of the class. But I can change it.

Copy link
Contributor

Choose a reason for hiding this comment

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

contains is clearer

Copy link
Contributor

Choose a reason for hiding this comment

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

I want to double check: do you mean contents.contains("...")?
Due to indentation the string might not be in the list of strings, but a substring of an element, which the findString-method seems to be created for in the same file.

Copy link
Contributor

Choose a reason for hiding this comment

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

That makes sense.

@pombredanne
Copy link

pombredanne commented Feb 9, 2024

@MartinWitt what's left to do to get this through?
FWIW, there is a cottage industry of smalls tools and scripts that are parsing this plugin output .... it would be awesome to have a structured JSON output!
Anything to help you need move this forward?

/**
* A dependency node visitor that serializes visited nodes to a writer using the JSON format.
*/
public class JsonDependencyNodeVisitor extends AbstractSerializingVisitor implements DependencyNodeVisitor {
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need to be public? It's easier to evolve and iterate on if it's not.

try {
writer.write(sb.toString());
} catch (IOException e) {
throw new RuntimeException("Error while writing json output", e);
Copy link
Contributor

Choose a reason for hiding this comment

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

needs a more specific exception. Looking at this now I notice that the superclass and interface are badly designed. They use a PrintWriter which swallows exceptions. That might need to be fixed.

Choose a reason for hiding this comment

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

What about just not catch an exception here and leaving this business to the callers.... fixing the PrintWriter could then be done in another patch and not here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixing PrintWriter should be a different PR but that might be a prerequisite for this PR. I'm not sure. It seems fine to let this method throw IOException and handle it further up the stack. RuntimeException is not OK.

@pombredanne
Copy link

Looking at the details of this PR, it feels to me that crafting the JSON by hand as done here feels like problems in the making with encoding or else. Should not this use a proper JSON library of sorts? Is not there one bundled in the standard Maven or Java and this plugin may therefore always have have one on hand?

(Sorry for these likely dumb questions: my Java skills need to brushing off)

@yahavi
Copy link

yahavi commented Mar 1, 2024

If it's useful to anyone, we've developed a Maven dependency tree plugin that generates a JSON dependency tree. Check it out at: https://github.com/jfrog/maven-dep-tree.

@monperrus
Copy link

@pombredanne @elharo if we are able to drive to merge, we can put more effort on this PR.

try {
writer.write(sb.toString());
} catch (IOException e) {
throw new RuntimeException("Error while writing json output", e);
Copy link
Contributor

Choose a reason for hiding this comment

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

Fixing PrintWriter should be a different PR but that might be a prerequisite for this PR. I'm not sure. It seems fine to let this method throw IOException and handle it further up the stack. RuntimeException is not OK.

*/
public void _testTreeJsonSerialzing() throws Exception {
List<String> contents = runTreeMojo("tree1.json", "json");
assertTrue(findString(contents, "\"testGroupId\": \"project\""));
Copy link
Contributor

Choose a reason for hiding this comment

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

contains is clearer

}

@Override
public boolean visit(DependencyNode node) {
Copy link
Contributor

Choose a reason for hiding this comment

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

add a test for this case, see what works

@LogFlames
Copy link
Contributor

Hi,
I'm working on getting this merged and incorporating the requested changes. Unfortunately I don't have access to Martin's fork and will need to create a new PR. Will build on Martin's branch and try to update all changes beforehand to make the transition as smooth as possible.

@elharo
Copy link
Contributor

elharo commented May 23, 2024

feature complete under another PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants