From 17f5f62e614e97fec696c6f0c62dcafeaeda1300 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 23 Apr 2024 07:09:30 +0100 Subject: [PATCH] feat: Clone repo when starting repo --- server-default.toml | 3 +++ src/server/actors/repo/mod.rs | 23 ++++++++++++++++++---- src/server/config/mod.rs | 21 +++++++++++++++----- src/server/gitforge/tests/common.rs | 2 +- src/server/gitforge/tests/forgejo.rs | 10 ++++++++-- src/server/mod.rs | 29 +++++++++++++++++++++++----- 6 files changed, 71 insertions(+), 17 deletions(-) diff --git a/server-default.toml b/server-default.toml index b8fd1b38..a08cdb0f 100644 --- a/server-default.toml +++ b/server-default.toml @@ -1,6 +1,9 @@ [webhook] url = "https://localhost:8080/webhook" +[storage] +path = "./data" + [forge.default] forge_type = "ForgeJo" hostname = "git.example.net" diff --git a/src/server/actors/repo/mod.rs b/src/server/actors/repo/mod.rs index 94e942b0..0899cfea 100644 --- a/src/server/actors/repo/mod.rs +++ b/src/server/actors/repo/mod.rs @@ -68,11 +68,26 @@ impl Actor for RepoActor { #[derive(Message)] #[rtype(result = "()")] -pub struct StartRepo; -impl Handler for RepoActor { +pub struct CloneRepo; +impl Handler for RepoActor { type Result = (); - fn handle(&mut self, _msg: StartRepo, ctx: &mut Self::Context) -> Self::Result { - info!(%self.details, "Starting Repo"); + fn handle(&mut self, _msg: CloneRepo, ctx: &mut Self::Context) -> Self::Result { + info!(%self.details, "Clone/Update Repo"); + let gitdir = self.details.gitdir.clone(); + match self.forge.repo_clone(gitdir) { + Ok(_) => ctx.address().do_send(LoadConfigFromRepo), + Err(err) => warn!(?err, "Could not Clone repo"), + } + } +} + +#[derive(Message)] +#[rtype(result = "()")] +pub struct LoadConfigFromRepo; +impl Handler for RepoActor { + type Result = (); + fn handle(&mut self, _msg: LoadConfigFromRepo, ctx: &mut Self::Context) -> Self::Result { + info!(%self.details, "Loading .git-next.toml from repo"); let details = self.details.clone(); let addr = ctx.address(); let forge = self.forge.clone(); diff --git a/src/server/config/mod.rs b/src/server/config/mod.rs index df8c584d..791f46b2 100644 --- a/src/server/config/mod.rs +++ b/src/server/config/mod.rs @@ -31,6 +31,10 @@ impl ServerConfig { .map(|(name, forge)| (ForgeName(name.clone()), forge)) } + pub const fn storage(&self) -> &ServerStorage { + &self.storage + } + pub const fn webhook(&self) -> &Webhook { &self.webhook } @@ -199,9 +203,6 @@ impl ServerRepoConfig { _ => None, } } - pub fn gitdir(&self) -> Option { - self.gitdir.clone().map(GitDir) - } } #[cfg(test)] impl AsRef for ServerRepoConfig { @@ -327,7 +328,7 @@ pub struct RepoDetails { pub branch: BranchName, pub forge: ForgeDetails, pub repo_config: Option, - pub gitdir: Option, + pub gitdir: GitDir, } impl RepoDetails { pub fn new( @@ -335,13 +336,19 @@ impl RepoDetails { server_repo_config: &ServerRepoConfig, forge_name: &ForgeName, forge: &ForgeConfig, + server_storage: &ServerStorage, ) -> Self { Self { repo_alias: name.clone(), repo_path: RepoPath(server_repo_config.repo.clone()), repo_config: server_repo_config.repo_config(), branch: BranchName(server_repo_config.branch.clone()), - gitdir: server_repo_config.gitdir(), + gitdir: GitDir( + server_storage + .path + .join(forge_name.to_string()) + .join(name.to_string()), + ), forge: ForgeDetails { forge_name: forge_name.clone(), forge_type: forge.forge_type.clone(), @@ -400,6 +407,10 @@ impl Display for ForgeType { #[derive(Debug, Clone, PartialEq, Eq, Deserialize)] pub struct GitDir(PathBuf); impl GitDir { + #[cfg(test)] + pub(crate) fn new(pathbuf: &std::path::Path) -> Self { + Self(pathbuf.to_path_buf()) + } #[allow(dead_code)] // TODO: pub const fn pathbuf(&self) -> &PathBuf { &self.0 diff --git a/src/server/gitforge/tests/common.rs b/src/server/gitforge/tests/common.rs index 2373b2ef..44b83ea7 100644 --- a/src/server/gitforge/tests/common.rs +++ b/src/server/gitforge/tests/common.rs @@ -32,7 +32,7 @@ pub fn repo_details( n: u32, forge: ForgeDetails, repo_config: Option, - gitdir: Option, + gitdir: GitDir, ) -> RepoDetails { RepoDetails { repo_alias: repo_alias(n), diff --git a/src/server/gitforge/tests/forgejo.rs b/src/server/gitforge/tests/forgejo.rs index aec90a31..611cb716 100644 --- a/src/server/gitforge/tests/forgejo.rs +++ b/src/server/gitforge/tests/forgejo.rs @@ -8,12 +8,15 @@ use super::*; #[test] fn test_name() { + let Ok(fs) = kxio::filesystem::FileSystem::new_temp() else { + panic!("fs") + }; let net = Network::new_mock(); let repo_details = common::repo_details( 1, common::forge_details(1, ForgeType::MockForge), Some(common::repo_config(1)), - None, + GitDir::new(fs.cwd()), ); let forge = Forge::new_forgejo(repo_details, net); assert_eq!(forge.name(), "forgejo"); @@ -21,6 +24,9 @@ fn test_name() { #[test_log::test(tokio::test)] async fn test_branches_get() { + let Ok(fs) = kxio::filesystem::FileSystem::new_temp() else { + panic!("fs") + }; let mut net = MockNetwork::new(); let hostname = common::hostname(1); let path = common::repo_path(1); @@ -36,7 +42,7 @@ async fn test_branches_get() { 1, common::forge_details(1, ForgeType::MockForge), Some(common::repo_config(1)), - None, + GitDir::new(fs.cwd()), ); let forge = Forge::new_forgejo(repo_details, net.clone()); diff --git a/src/server/mod.rs b/src/server/mod.rs index 44833722..5c40dfc5 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -15,7 +15,7 @@ use crate::{ filesystem::FileSystem, server::{ actors::webhook, - config::{ForgeConfig, ForgeName, RepoAlias, Webhook}, + config::{ForgeConfig, ForgeName, RepoAlias, ServerStorage, Webhook}, }, }; @@ -55,9 +55,13 @@ pub async fn start(fs: FileSystem, net: Network) { let webhook_router = webhook::WebhookRouter::new().start(); let webhook = server_config.webhook(); + let server_storage = server_config.storage(); + server_config .forges() - .flat_map(|(forge_name, forge)| create_forge_repos(forge, forge_name, webhook, &net)) + .flat_map(|(forge_name, forge)| { + create_forge_repos(forge, forge_name, server_storage, webhook, &net) + }) .map(start_actor) .map(|(alias, addr)| webhook::AddWebhookRecipient(alias, addr.recipient())) .for_each(|msg| webhook_router.do_send(msg)); @@ -70,6 +74,7 @@ pub async fn start(fs: FileSystem, net: Network) { fn create_forge_repos( forge: &ForgeConfig, forge_name: ForgeName, + server_storage: &ServerStorage, webhook: &Webhook, net: &Network, ) -> Vec<(ForgeName, RepoAlias, RepoActor)> { @@ -79,16 +84,24 @@ fn create_forge_repos( info!("Creating Forge"); forge .repos() - .map(create_actor(forge_name, forge.clone(), webhook, net)) + .map(create_actor( + forge_name, + forge.clone(), + server_storage, + webhook, + net, + )) .collect::>() } fn create_actor( forge_name: ForgeName, forge: config::ForgeConfig, + server_storage: &ServerStorage, webhook: &Webhook, net: &Network, ) -> impl Fn((RepoAlias, &ServerRepoConfig)) -> (ForgeName, RepoAlias, RepoActor) { + let server_storage = server_storage.clone(); let webhook = webhook.clone(); let net = net.clone(); move |(repo_name, server_repo_config)| { @@ -96,7 +109,13 @@ fn create_actor( let _guard = span.enter(); info!("Creating Repo"); let actor = actors::repo::RepoActor::new( - config::RepoDetails::new(&repo_name, server_repo_config, &forge_name, &forge), + config::RepoDetails::new( + &repo_name, + server_repo_config, + &forge_name, + &forge, + &server_storage, + ), webhook.clone(), net.clone(), ); @@ -113,7 +132,7 @@ fn start_actor( let _guard = span.enter(); info!("Starting"); let addr = actor.start(); - addr.do_send(actors::repo::StartRepo); + addr.do_send(actors::repo::CloneRepo); info!("Started"); (repo_alias, addr) }