diff --git a/techtree-manager/src/collect.rs b/techtree-manager/src/collect.rs index 9a2d6ba..ef3eca1 100644 --- a/techtree-manager/src/collect.rs +++ b/techtree-manager/src/collect.rs @@ -24,7 +24,7 @@ pub async fn collect_tree(ctx: &crate::Context) -> anyhow::Result anyhow::Result anyhow::Result { - if has_ultimate_label { - crate::tree::ElementStatus::UltimateGoal - } else if has_completed_label { + if has_completed_label { crate::tree::ElementStatus::Completed } else if issue.assignee.is_some() - || issue.assignees.as_ref().is_some_and(|v| !v.is_empty()) + || issue + .assignees + .as_ref() + .map(|v| v.len() > 0) + .unwrap_or(false) { crate::tree::ElementStatus::Assigned } else { diff --git a/techtree-manager/src/issue.rs b/techtree-manager/src/issue.rs index 51f33f0..97cf9d9 100644 --- a/techtree-manager/src/issue.rs +++ b/techtree-manager/src/issue.rs @@ -57,14 +57,14 @@ pub async fn find_bot_comment( .rev() .find(|comment| comment.user.as_ref().and_then(|u| u.id) == Some(-2)); - maybe_bot_comment + Ok(maybe_bot_comment .map(|c| -> anyhow::Result<_> { Ok(BotCommentInfo { body: c.body.clone().unwrap_or("".to_owned()), id: c.id.context("Missing id for the bot comment")?, }) }) - .transpose() + .transpose()?) } /// Find existing bot comment or create a new one. @@ -115,12 +115,12 @@ pub async fn update_bot_comment_from_subtree( subtree: &crate::tree::Subtree<'_>, hash: &str, ) -> anyhow::Result<()> { - let mut mermaid = subtree.to_mermaid(ctx.repo_url.as_ref(), false); + let mut mermaid = subtree.to_mermaid(&ctx.repo_url.to_string(), false); // When the mermaid graph gets too big, regenerate a simplified version. if mermaid.len() > 4990 { log::info!("Mermaid graph is too big, generating simplified version..."); - mermaid = subtree.to_mermaid(ctx.repo_url.as_ref(), true); + mermaid = subtree.to_mermaid(&ctx.repo_url.to_string(), true); } let full_text = if mermaid.len() > 4990 { @@ -143,7 +143,7 @@ _Sorry, the partial techtree is still too big to be displayed for this element.. ) }; - update_bot_comment(ctx, id, full_text).await?; + update_bot_comment(&ctx, id, full_text).await?; Ok(()) } @@ -157,7 +157,8 @@ pub async fn remove_stale_label(ctx: &crate::Context, issue_number: u64) -> anyh let stale_label_id = labels .iter() - .find(|l| l.name.as_deref() == Some("Stale")) + .filter(|l| l.name.as_deref() == Some("Stale")) + .next() .map(|l| l.id.ok_or(anyhow::anyhow!("`Stale` label has no ID"))) .transpose()?; diff --git a/techtree-manager/src/main.rs b/techtree-manager/src/main.rs index 6a3c027..eda6053 100644 --- a/techtree-manager/src/main.rs +++ b/techtree-manager/src/main.rs @@ -1,7 +1,4 @@ #![allow(dead_code)] -#![allow(clippy::useless_format)] -#![allow(clippy::needless_return)] -#![deny(clippy::as_conversions)] use anyhow::Context as _; use forgejo_api::Forgejo; @@ -72,7 +69,7 @@ async fn run() -> anyhow::Result<()> { .map(|token| -> Result<_, ()> { let mut repo_auth_url = repo_url.clone(); repo_auth_url.set_username("forgejo-actions")?; - repo_auth_url.set_password(Some(token))?; + repo_auth_url.set_password(Some(&token))?; Ok(repo_auth_url) }) .transpose() @@ -148,9 +145,7 @@ async fn run() -> anyhow::Result<()> { } 'issues: for issue in tree.iter_issues() { - let subtree = tree - .subtree_for_issue(issue) - .expect("issue from tree not found in tree"); + let subtree = tree.subtree_for_issue(issue).expect("issue from tree not found in tree"); let hash = subtree.stable_hash(); let (bot_comment, _is_new) = issue::find_or_make_bot_comment(&ctx, issue) diff --git a/techtree-manager/src/render.rs b/techtree-manager/src/render.rs index ca3682a..f18bebb 100644 --- a/techtree-manager/src/render.rs +++ b/techtree-manager/src/render.rs @@ -52,14 +52,14 @@ pub async fn render( std::fs::create_dir(&info.repo_dir).context("Failed creating directory for rendered graph")?; let dot_source = tree.to_dot(); - std::fs::write(info.dot_file(), dot_source.as_bytes()) + std::fs::write(&info.dot_file(), dot_source.as_bytes()) .context("Failed to write `dot` source file")?; Command::new("dot") .args(["-T", "svg"]) .arg("-o") - .arg(info.svg_file()) - .arg(info.dot_file()) + .arg(&info.svg_file()) + .arg(&info.dot_file()) .success() .context("Failed to generate svg graph from dot source")?; diff --git a/techtree-manager/src/tree.rs b/techtree-manager/src/tree.rs index d64c78c..3ec271f 100644 --- a/techtree-manager/src/tree.rs +++ b/techtree-manager/src/tree.rs @@ -55,7 +55,6 @@ impl Element { let (color, background) = match (subtree_role, status) { (Some(SubtreeElementRole::ElementOfInterest), _) => ("black", "white"), (Some(SubtreeElementRole::Dependant), _) => ("gray", "gray"), - (_, ElementStatus::UltimateGoal) => ("black", "white"), (_, ElementStatus::Missing) => ( "#800", // Highlight root elements @@ -101,7 +100,6 @@ impl Element { let class = match (role, status) { (Some(SubtreeElementRole::ElementOfInterest), _) => "eoi", (Some(SubtreeElementRole::Dependant), _) => "dependant", - (_, ElementStatus::UltimateGoal) => "ultimate", (_, ElementStatus::Missing) => "dep_missing", (_, ElementStatus::Assigned) => "dep_assigned", (_, ElementStatus::Completed) => "dep_completed", @@ -118,7 +116,6 @@ fn mermaid_classes() -> String { r##" classDef eoi fill:#fff, stroke:#000, color:#000; classDef dependant fill:#fff, stroke:#888, color:#888; - classDef ultimate fill:#fff, stroke:#000, color:#000; classDef dep_missing fill:#fcc, stroke:#800, color:#000; classDef dep_assigned fill:#ffa, stroke:#a50, color:#000; classDef dep_completed fill:#afa, stroke:#080, color:#000; @@ -131,7 +128,6 @@ pub enum ElementStatus { Missing, Assigned, Completed, - UltimateGoal, } impl std::fmt::Display for ElementStatus { @@ -140,7 +136,6 @@ impl std::fmt::Display for ElementStatus { ElementStatus::Missing => "MISSING", ElementStatus::Assigned => "ASSIGNED", ElementStatus::Completed => "COMPLETED", - ElementStatus::UltimateGoal => "ULTIMATE GOAL", }) } } @@ -199,24 +194,13 @@ impl Tree { } pub fn iter_ultimate_elements<'a>(&'a self) -> impl Iterator + 'a { - self.graph - .node_indices() - .filter(|index| { - self.graph.node_weight(*index).unwrap().status == ElementStatus::UltimateGoal - }) - .filter(|index| { - // Ultimate goal elements must not have any incoming dependency edges. Warn and - // ignore it, if one does. - let has_no_incoming = self.graph - .neighbors_directed(*index, petgraph::Direction::Incoming) - .next() - .is_none(); - if !has_no_incoming { - let el = self.graph.node_weight(*index).unwrap(); - log::warn!("Element #{} is marked \"Ultimate Goal\" but is depended on by others? Ignoring...", el.issue_number); - } - has_no_incoming - }) + self.graph.node_indices().filter(|index| { + // If there are no incoming edges, then this is an ultimate element! + self.graph + .neighbors_directed(*index, petgraph::Direction::Incoming) + .next() + .is_none() + }) } pub fn get_element_role(&self, element: ElementIndex) -> ElementRole { @@ -279,7 +263,7 @@ impl Tree { for index in self.graph.node_indices() { mermaid.push_str(&self.graph[index].to_mermaid_node(index, None, repo_url, simple)); - mermaid.push('\n'); + mermaid.push_str("\n"); } for edge in self.graph.edge_references() { @@ -413,7 +397,7 @@ impl<'a> Subtree<'a> { repo_url, simple, )); - mermaid.push('\n'); + mermaid.push_str("\n"); } for edge in self.graph.edge_references() { diff --git a/techtree-manager/src/wiki.rs b/techtree-manager/src/wiki.rs index d38a775..e61f931 100644 --- a/techtree-manager/src/wiki.rs +++ b/techtree-manager/src/wiki.rs @@ -5,7 +5,7 @@ pub async fn update_wiki_from_tree( ctx: &crate::Context, tree: &crate::tree::Tree, ) -> anyhow::Result<()> { - let mermaid = tree.to_mermaid(ctx.repo_url.as_ref(), false); + let mermaid = tree.to_mermaid(&ctx.repo_url.to_string(), false); let wiki_text = format!( r##"This page is automatically updated to show the latest and greatest FAFO techtree: @@ -14,7 +14,7 @@ pub async fn update_wiki_from_tree( ``` "## ); - update_wiki_overview(ctx, wiki_text) + update_wiki_overview(&ctx, wiki_text) .await .context("Failed to update the techtree wiki page")?; Ok(())