Skip to content

Conversation

@belmarca-bia
Copy link

Summary

This PR adds support for outputting JSON using the tree command. It refactored the visitor code in order to call abstract procedures instead of hardcoding the textual representation.

Test Plan

The tests (cargo test) passed.

@konstin
Copy link
Member

konstin commented Oct 24, 2025

Can you share the JSON format you chose for a real project, how does it compare to uv pip list --format json?

It seems that you change the iteration based code to a much more complex visitor based one. What motivated this change?

@belmarca-bia
Copy link
Author

This does something different from uv pip list, which just lists dependencies. It only adds a JSON tree emitter in addition to the default textual tree emitter. I'm interested in the dependency tree and not the the dependencies themselves. This would be used to taint packages/libraries to know which tests to run during CI.

I don't particularly care about the actual key names or such details for now, nor do I care about the actual implementation identifiers, etc. Just testing the waters to see if that's the kind of functionality that could be added to uv.

As for the bigger complexity, the advantage is uv can now serialize the dependency graph in multiple formats much more easily. The textual one is not great to pass as a input to another program, for example! The current code and the new code are actually functionally similar, they both run depth-first except the new code is now an actual visitor instead of just using the name visitor. The old method is kept in case for now but would have to go as it's basically hard-coding the serialization implementation.

-            for (visited_index, visited_line) in self.visit(*dep, visited, path).iter().enumerate()
-            {
-                let prefix = if visited_index == 0 {
-                    prefix_top
-                } else {
-                    prefix_rest
-                };
-                lines.push(format!("{prefix}{visited_line}"));
-            }
+            self.visit_with_formatter(*dep, formatter, visited, path, child_position);

Note that the current pattern could (should) be abstracted a little bit more as it is not limited to formatting and serializing. This same pattern could allow uv to perform any computation on the graph, basically.

Thanks for taking a look!

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.

3 participants