diff --git a/Cargo.lock b/Cargo.lock index 3e89a29..b5e392a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,6 +117,12 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "as-any" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a30a44e99a1c83ccb2a6298c563c888952a1c9134953db26876528f84c93a" + [[package]] name = "askama" version = "0.12.0" @@ -436,6 +442,7 @@ name = "clowarden-core" version = "0.1.0" dependencies = [ "anyhow", + "as-any", "async-trait", "base64 0.21.4", "cached", diff --git a/Cargo.toml b/Cargo.toml index 7a2c8ea..80881f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ rust-version = "1.70" [workspace.dependencies] anyhow = "1.0.75" +as-any = "0.3.1" askama = "0.12.0" async-trait = "0.1.73" axum = { version = "0.6.20", features = ["macros"] } diff --git a/clowarden-core/Cargo.toml b/clowarden-core/Cargo.toml index e9646cc..90f30a0 100644 --- a/clowarden-core/Cargo.toml +++ b/clowarden-core/Cargo.toml @@ -8,6 +8,7 @@ rust-version.workspace = true [dependencies] anyhow = { workspace = true } +as-any = { workspace = true } async-trait = { workspace = true } base64 = { workspace = true } cached = { workspace = true } diff --git a/clowarden-core/src/services/github/mod.rs b/clowarden-core/src/services/github/mod.rs index 16d88c9..cb41f73 100644 --- a/clowarden-core/src/services/github/mod.rs +++ b/clowarden-core/src/services/github/mod.rs @@ -12,6 +12,7 @@ use crate::{ services::ChangeApplied, }; use anyhow::{Context, Result}; +use as_any::Downcast; use async_trait::async_trait; use tracing::debug; @@ -132,13 +133,26 @@ impl ServiceHandler for Handler { } // Apply repositories changes - for change in changes.repositories { + 'changes_repositories: for change in changes.repositories { let err = match &change { RepositoryChange::RepositoryAdded(repo) => self.svc.add_repository(&ctx, repo).await.err(), RepositoryChange::TeamAdded(repo_name, team_name, role) => { self.svc.add_repository_team(&ctx, repo_name, team_name, role).await.err() } RepositoryChange::TeamRemoved(repo_name, team_name) => { + // If the team has just been deleted from the directory in + // this reconciliation, there is no need to remove it from + // the repository as this will be done automatically when + // the team is deleted from GitHub + for entry in &changes_applied { + let change = (*entry.change).downcast_ref::(); + if let Some(DirectoryChange::TeamRemoved(team_removed_name)) = change { + if team_name == team_removed_name { + continue 'changes_repositories; + } + } + } + self.svc.remove_repository_team(&ctx, repo_name, team_name).await.err() } RepositoryChange::TeamRoleUpdated(repo_name, team_name, role) => { diff --git a/clowarden-core/src/services/mod.rs b/clowarden-core/src/services/mod.rs index b189fa0..de2d93e 100644 --- a/clowarden-core/src/services/mod.rs +++ b/clowarden-core/src/services/mod.rs @@ -3,6 +3,7 @@ use crate::{cfg::Organization, github::Source}; use anyhow::Result; +use as_any::AsAny; use async_trait::async_trait; use std::fmt::Debug; @@ -46,7 +47,7 @@ pub struct ChangeApplied { } /// Trait that defines some operations a Change implementation must support. -pub trait Change: Debug { +pub trait Change: AsAny + Debug { /// Return some details about the change. fn details(&self) -> ChangeDetails;