-
Notifications
You must be signed in to change notification settings - Fork 3.5k
mix xref graph --group
#11943
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
mix xref graph --group
#11943
Conversation
|
Hi @marcandre! Thanks for the PR and the context. Here is what I propose. Introduce a You can create as many groups as you want. Would this work? |
|
So what you are proposing to rename What about |
Whatever you believe is best. If list of files, it should be separated by
That's the part I don't fully grasp. With the |
I'd go with files, as they are the basis of Allowing multiple paths in a single argument seems good. Should we allow it for
You are correct that defmodule Bobby.MyBehaviour do
# Bring in standard aliases
use Bobby
# Define behavior
@callback example(my_arg :: %MyAppSchema{}) :: :ok
endI don't want to include this file in the group. The list of these behaviors or modules with macros is much more subject to change than the core dependencies does. I want to keep the group minimal and stable. Adding Having also |
|
So let's go with --group and make it file based. The only reason I want to support multiple files on group is because we probably want to allow distinct groups to be created. The other flags do not have such requirement. :) |
cae573e to
5aaa6e1
Compare
|
I'll see if I can make a better case for PR amended for only Should there be an error or warning if a given |
lib/mix/lib/mix/tasks/xref.ex
Outdated
| reduce: {file_references, %{}} do | ||
| {file_references, aliases} -> | ||
| group_paths | ||
| |> String.split("|") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gah, I just realized that | is the pipe operator on the shell, so we will need quoting... or we need to pick something else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had another idea... what if we allow this to be specified in the mix.exs instead? We already have a xref key, we could do this:
xref: [
groups: [
"lib-use-modules": ~w(lib/foo.ex lib/foo/web.ex)
]
]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd use commas as delimiter (even if technically one could have them in their paths)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had another idea... what if we allow this to be specified in the
mix.exsinstead?
So... this would apply to every run of mix xref graph??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe in the future we could have --ungroup lib-use-modules but if we have to ungroup... then perhaps that's not the best idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In any case, if we are sticking with --group, agreed on using , as delimiter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. WDYT?
It doesn't seem intuitive nor really workable to me. In particular, if there is an unexpected dependency from the group, then one will want to inspect the graph with --lib/foo.ex but that won't be available anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Time for bed, maybe I'll wake up with a different opinion 😸
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edited with commas
ad11595 to
8a16ff0
Compare
|
💚 💙 💜 💛 ❤️ |
Summary
mix xref graph --label compile-connectedwould benefit from a way to deal with an acceptable list of core dependencies that should be excluded, provided they don't have any outside dependencies.I am proposing a
--trimAPI to merge these core paths and remove the resulting group after verifying it has no dependency. The command--mergeexposes the merging part without the deletion.Details
Use case
We have a CI script that insures we don't introduce transitive compile-time dependencies, using
--label compile-connectedand--fail-above 0.One complexity is that we have a core of compile-time dependencies that are in more than a single file. In particular, in the same way that we have
use BobbyWeb, :somethingin most of the web layer, we haveuse Bobbyused in the app layer, and web layer viause BobbyWeb, and these may import some basic macros (e.g.sigil_dfor decimals).To have
--label compile-connectednot be triggered because of these, what we currently do is we--excludeall these core paths.We must then run
mix xref graphagain to insure that these core paths do not themselves refer to anything else outside this core (any type of dependency).Let's say we have 3 core paths
A,BandC, a first attempt looks like:That won't work if there are dependencies between
A,BandCthough, so if one wants a generic way to do this for the three paths, the solution looks like:This makes for an ugly and inefficient solution.
Merge
This PR adds a
--mergecommand to merge many files into a group via vertex identification.Any file that depended on any component of the group will depend on the resulting group; duplicates are removed and highest type of dependency is selected (compile > export > runtime)
The group will similarly depend on any file that any of its components depended on.
Dependencies between members of the group are removed.
Trim
This PR adds a
--trimcommand which does exactly what--mergedoes, but then proceeds to fail if the resulting group has any dependency, or else it excludes it.The usecase above can then be resolved with:
Questions
It wasn't immediately clear what solution I wanted to come up with so I started coding the
mergefunctionality first. It's only later that I realized that I really wanted thetrimfunctionality. I am not even sure that the--trimis the best API (my Covid brain isn't helping 😅 )I am unsure how useful the
--mergecommand can be. If it is deemed preferable to remove it, I could probably come up with a simpler (but maybe uglier) implementation for--trim, because the generic operations are more complex than themerge-check-deletecombination. In particular it takes care of selecting the highest type of dependency when deduping them, only to see them be removed later... I found it ironic that the erlang order of:compile,:exportandnil(i.e. runtime) happened to be exactly what I wanted it to be, but I chose to be explicit about it in my implementation.