-
Notifications
You must be signed in to change notification settings - Fork 16
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
supporting graph generation based on input dependency #36
supporting graph generation based on input dependency #36
Conversation
Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com>
Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com>
Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com>
cmd/graph.go
Outdated
} | ||
// main module can never be a neighbour | ||
for _, neighbour := range depGraph[dep] { | ||
if dep == mainModule { |
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.
potentially you could extract the nodes creation to func and reuse it here as well as in the other branch
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 have switched to strings.Join()
for the if
block but in the else
block, reusing the code won't be possible IMO.
This is because for generating the graph based on an input dependency our .dot
file looks like (the if
block):
"A" -> "B" -> "C" -> "D"
"E" -> "F" -> "G" -> "H"
.
.
.
but for generating the graph of the entire dependency tree it looks like(the else
block):
"A" -> "B"
"B" -> "C"
"C" -> "D"
"E" -> "F"
"F" -> "G"
"G" -> "H"
Now we could have the second graph also look like the first one but for that we would need access to all the chains like we have incase of the first graph. Getting these chains using the getAllChains
function is both time and memory intensive so it'd be better to avoid it. Thoughts?
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.
Hmm I see, I think I am lacking an understanding what's the difference between the two branches 🤔 Why is it different?
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.
So we support making two types of graphs:
- based on a dependency a user enters
- graph of all dependencies
To create the graph of all dependencies the logic is simple. We iterate through each dependency and then iterate through its neighbors and have all the edges of the graph in the .dot
file like this:
"A" -> "B"
"B" -> "C"
"C" -> "D"
"E" -> "F"
"F" -> "G"
"G" -> "H"
But for the graph based on the dependency entered by the user, we need access to all dependency chains. This is because we need to check which chain has the dependency entered by the user. Once we know that we simply put those chains in the .dot
file:
"A" -> "B" -> "C" -> "D"
"E" -> "F" -> "G" -> "H"
1. Why can't we reuse the logic by abstracting it to a function?
Reusing the logic would mean having the graph of all dependencies in a format similar to the graph based on the dependency entered by the user.
And to create this graph in a similar format, we would need access to all dependency chains.
2. What's the problem in getting access to all dependency chains?
To get these chains we call the getAllChains()
function. This function is very demanding in terms of memory and also takes a lot of time, so we should ideally try to avoid calling it. Since we can get the graph of all dependencies without calling this function I didn't use it.
Does this make more sense? 😅 Also, I'm currently refactoring the code in this file into separate functions and will push that tomorrow, which would help seeing the difference a bit more clearly.
fileContents := "strict digraph {\ngraph [overlap=false];\n" | ||
|
||
// graph to be generated is based around input dep | ||
if dep != "" { |
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 think we should also add some tests, I see that this whole function does not have any...
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 let's do a function that received depGraph as parameter, and then we can assert output of both branches of the if here. 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.
I'm currently refactoring the code in this file into separate functions
Yup was doing that only :)
Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com>
Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com>
@alenkacz I've abstracted the logic for the if and else blocks into separate functions. Hope this provided some more clarity. I've also added tests for all the functions being used in that file 🙂 |
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.
Last two nits, and we're there :) thanks for your patience!
cmd/graph.go
Outdated
// get the contents of the .dot file for the graph | ||
// when the -d flag is set | ||
func getFileContentsForSingleDep(chains []Chain, dep string) string { | ||
data := "" |
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.
nit: you could skip this and start with what's on line 85
cmd/graph.go
Outdated
func getFileContentsForAllDeps(deps []string, depGraph map[string][]string, mainModule string) string { | ||
data := "" | ||
// color the main module as yellow | ||
data += fmt.Sprintf("MainNode [label=\"%s\", style=\"filled\" color=\"yellow\"]\n", mainModule) |
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.
this is shared between the function, maybe we could extract it to func with dependency of module name
Signed-off-by: RinkiyaKeDad <arshsharma461@gmail.com>
Thanks for reviewing @alenkacz! Made the changes. Please drop a "lgtm" to merge this if they're okay 🙃 |
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.
🚢
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: alenkacz, RinkiyaKeDad The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Fixes #24