Skip to content

Fix dependency tracking and show shortest path dependency cycle #151

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

Merged
merged 6 commits into from
Mar 12, 2025

Conversation

jfrolich
Copy link
Collaborator

No description provided.

Copy link
Member

@rolandpeelen rolandpeelen left a comment

Choose a reason for hiding this comment

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

Nice! Left some notes 👌

@@ -330,7 +330,7 @@ pub fn incremental_build(
pb.finish();
}

log::error!("Could not parse source files: {}", &err);
println!("Could not parse source files: {}", &err);
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps log::warn! or log::info! here instead? println! cannot be supressed by log levels

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The log::error etc are prepended with ERROR: it's a bit ugly if it's expected output of the application

@@ -405,7 +405,7 @@ pub fn incremental_build(
pb.finish();
if !compile_errors.is_empty() {
if helpers::contains_ascii_characters(&compile_warnings) {
log::error!("{}", &compile_warnings);
println!("{}", &compile_warnings);
Copy link
Member

Choose a reason for hiding this comment

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

Same

@@ -417,7 +417,7 @@ pub fn incremental_build(
default_timing.unwrap_or(compile_duration).as_secs_f64()
);
}
log::error!("{}", &compile_errors);
println!("{}", &compile_errors);
Copy link
Member

Choose a reason for hiding this comment

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

Same

@@ -282,7 +282,7 @@ pub fn start(
)
.await
{
log::error!("{:?}", e)
println!("{:?}", e)
Copy link
Member

Choose a reason for hiding this comment

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

log::info!

let deps: Vec<String> = module.deps.iter().cloned().collect();

// Update the graph
*graph.get_mut(&name.to_string()).unwrap() = deps.clone();
Copy link
Member

Choose a reason for hiding this comment

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

I don't think you have to do this clone here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We couldn't, but I could swap the next statement with this one and only borrow there 👍

return stack;
// Second pass: build the graph and count in-degrees
for (name, module) in modules {
let deps: Vec<String> = module.deps.iter().cloned().collect();
Copy link
Member

Choose a reason for hiding this comment

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

It could be that you can do into_iter() which will consume the iterator straight away? Could be the other way around though - not 100% sure, but one of them is more optimal

stack.push(module_name.to_string())
// OPTIMIZATION 1: Start with nodes that are more likely to be in cycles
// Sort nodes by their connectivity (in-degree + out-degree)
let mut start_nodes: Vec<String> = graph.keys().cloned().collect();
Copy link
Member

Choose a reason for hiding this comment

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

I think you can first filter out all graph keys that don't have any edges connected to them here. I think the check might be happening later, but we can just drop them here.

Also - I'm not sure if you need to clone these here

// Sort nodes by their connectivity (in-degree + out-degree)
let mut start_nodes: Vec<String> = graph.keys().cloned().collect();
start_nodes.sort_by(|a, b| {
let a_connectivity = in_degrees.get(a).unwrap_or(&0) + graph.get(a).map_or(0, |v| v.len());
Copy link
Member

Choose a reason for hiding this comment

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

If in_degrees is 0 here, or you can't get them, we should ignore them, they can't be part of a cycle by definition

@jfrolich jfrolich merged commit 04ffb68 into master Mar 12, 2025
2 checks passed
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.

2 participants