git-next/src/server/actors/repo/mod.rs

173 lines
5 KiB
Rust
Raw Normal View History

mod branch;
2024-04-09 10:44:01 +01:00
mod config;
pub mod status;
mod webhook;
2024-04-09 10:44:01 +01:00
use actix::prelude::*;
use kxio::network::Network;
use tracing::{info, warn};
2024-04-09 10:44:01 +01:00
use crate::server::{
config::{RepoConfig, RepoDetails},
forge,
git::Git,
};
2024-04-09 10:44:01 +01:00
use self::webhook::WebhookId;
2024-04-09 10:44:01 +01:00
pub struct RepoActor {
details: RepoDetails,
config: Option<RepoConfig>, // INFO: if [None] then send [StartRepo] to populate it
webhook_id: Option<WebhookId>, // INFO: if [None] then no webhook is configured
2024-04-09 10:44:01 +01:00
net: Network,
git: Git,
2024-04-09 10:44:01 +01:00
}
impl RepoActor {
pub(crate) const fn new(details: RepoDetails, net: Network, git: Git) -> Self {
2024-04-09 10:44:01 +01:00
Self {
details,
config: None,
webhook_id: None,
2024-04-09 10:44:01 +01:00
net,
git,
2024-04-09 10:44:01 +01:00
}
}
}
impl Actor for RepoActor {
type Context = Context<Self>;
fn stopping(&mut self, ctx: &mut Self::Context) -> Running {
match self.webhook_id.take() {
Some(webhook_id) => {
let repo_details = self.details.clone();
let net = self.net.clone();
webhook::unregister(webhook_id, repo_details, net)
.into_actor(self)
.wait(ctx);
Running::Continue
}
None => Running::Stop,
}
}
2024-04-09 10:44:01 +01:00
}
#[derive(Message)]
#[rtype(result = "()")]
pub struct StartRepo;
impl Handler<StartRepo> for RepoActor {
type Result = ();
fn handle(&mut self, _msg: StartRepo, ctx: &mut Self::Context) -> Self::Result {
info!(%self.details, "Starting Repo");
let details = self.details.clone();
let addr = ctx.address();
let net = self.net.clone();
config::load(details, addr, net).into_actor(self).wait(ctx);
}
}
#[derive(Message)]
#[rtype(result = "()")]
struct LoadedConfig(pub RepoConfig);
impl Handler<LoadedConfig> for RepoActor {
type Result = ();
fn handle(&mut self, msg: LoadedConfig, ctx: &mut Self::Context) -> Self::Result {
2024-04-09 10:44:01 +01:00
let config = msg.0;
info!(%self.details, %config, "Config loaded");
self.config.replace(config);
ctx.address().do_send(ValidateRepo);
}
}
#[derive(Message)]
#[rtype(result = "()")]
pub struct ValidateRepo;
impl Handler<ValidateRepo> for RepoActor {
type Result = ();
fn handle(&mut self, _msg: ValidateRepo, ctx: &mut Self::Context) -> Self::Result {
if let Some(repo_config) = self.config.clone() {
let repo_details = self.details.clone();
let addr = ctx.address();
let net = self.net.clone();
let git = self.git.clone();
branch::validate_positions(repo_details, repo_config, addr, git, net)
.into_actor(self)
.wait(ctx);
}
2024-04-09 10:44:01 +01:00
}
}
#[derive(Debug, Message)]
#[rtype(result = "()")]
pub struct StartMonitoring {
pub main: forge::Commit,
pub next: forge::Commit,
pub dev: forge::Commit,
pub dev_commit_history: Vec<forge::Commit>,
}
impl Handler<StartMonitoring> for RepoActor {
type Result = ();
fn handle(&mut self, msg: StartMonitoring, ctx: &mut Self::Context) -> Self::Result {
let Some(repo_config) = self.config.clone() else {
warn!("No config loaded");
return;
};
let next_ahead_of_main = msg.main != msg.next;
let dev_ahead_of_next = msg.next != msg.dev;
info!(%msg.main, %msg.next, %msg.dev, next_ahead_of_main, dev_ahead_of_next, "StartMonitoring");
let repo_details = self.details.clone();
let addr = ctx.address();
let net = self.net.clone();
let git = self.git.clone();
if next_ahead_of_main {
status::check_next(msg.next, repo_details, addr, net)
.into_actor(self)
.wait(ctx);
} else if dev_ahead_of_next {
branch::advance_next(
msg.next,
msg.dev_commit_history,
repo_details,
repo_config,
addr,
git,
)
.into_actor(self)
.wait(ctx);
} else if self.webhook_id.is_none() {
webhook::register(repo_details, addr, net)
.into_actor(self)
.wait(ctx);
}
}
}
#[derive(Message)]
#[rtype(result = "()")]
pub struct WebhookRegistered(pub WebhookId);
impl Handler<WebhookRegistered> for RepoActor {
type Result = ();
fn handle(&mut self, msg: WebhookRegistered, _ctx: &mut Self::Context) -> Self::Result {
self.webhook_id.replace(msg.0);
}
}
#[derive(Message)]
#[rtype(result = "()")]
pub struct AdvanceMainTo(pub forge::Commit);
impl Handler<AdvanceMainTo> for RepoActor {
type Result = ();
fn handle(&mut self, msg: AdvanceMainTo, ctx: &mut Self::Context) -> Self::Result {
let repo_details = self.details.clone();
let Some(repo_config) = self.config.clone() else {
warn!("No config loaded");
return;
};
let git = self.git.clone();
branch::advance_main(msg.0, repo_details, repo_config, git)
.into_actor(self)
.wait(ctx);
}
}