Skip to content
Clone
69f12aa
103 lines 3.1 KB Rust
use std::sync::Arc;
use export::AppRedis;
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
use uuid::Uuid;
use crate::context::facade::GitContext;
use crate::service::GitService;
use crate::smart::error::{SmartError, SmartResult};
use crate::smart::push::{NoopPushBackend, PushCoordinator, PushOperations, RedisPushBackend};
use crate::sync::queue::SyncQueue;
use config::git::SyncSettings;
#[derive(Clone)]
pub struct SmartService {
pub git: GitService,
pub kv: Option<Arc<AppRedis>>,
pub queue: Option<Arc<SyncQueue>>,
pub sync_settings: SyncSettings,
/// When set, pushes also publish a CI event on this Redis list topic.
pub ci_event_topic: Option<String>,
}
impl SmartService {
pub fn new(git: GitService) -> Self {
Self {
git,
kv: None,
queue: None,
sync_settings: SyncSettings::default(),
ci_event_topic: None,
}
}
pub fn with_ci_event_topic(mut self, topic: Option<String>) -> Self {
self.ci_event_topic = topic;
self
}
pub fn ci_event_topic(&self) -> Option<&str> {
self.ci_event_topic.as_deref()
}
pub fn with_kv(mut self, kv: Option<Arc<AppRedis>>) -> Self {
self.kv = kv;
self
}
pub fn with_queue(mut self, queue: Option<Arc<SyncQueue>>) -> Self {
self.queue = queue;
self
}
pub fn with_sync_settings(mut self, settings: SyncSettings) -> Self {
self.sync_settings = settings;
self
}
pub fn push_coordinator(&self) -> PushCoordinator {
let backend: Arc<dyn PushOperations> = match &self.kv {
Some(kv) => Arc::new(RedisPushBackend { kv: kv.clone() }),
None => Arc::new(NoopPushBackend),
};
PushCoordinator::new(backend)
}
pub fn bare_path(&self, ctx: &GitContext) -> std::path::PathBuf {
ctx.repo_dir()
}
pub async fn resolve(&self, space: &str, repo: &str) -> SmartResult<GitContext> {
self.git
.context(space.to_string(), repo.to_string())
.await
.map_err(|e| match e {
crate::share::errors::GitError::NotFound => {
SmartError::NotFound(format!("repo {space}/{repo}"))
}
other => SmartError::from(other),
})
}
pub async fn owning_space_id(&self, ctx: &GitContext) -> SmartResult<Uuid> {
let space_name = self.space_for(ctx).await?;
let Some(space) = models::space::spaces::Entity::find()
.filter(models::space::spaces::Column::LowerName.eq(space_name.to_lowercase()))
.one(self.git.db_read())
.await?
else {
return Err(SmartError::NotFound(format!("space {space_name}")));
};
Ok(space.id)
}
async fn space_for(&self, ctx: &GitContext) -> SmartResult<String> {
let space = crate::share::access::space_for_dir(self.git.db_read(), ctx.model.dir_id)
.await?
.ok_or_else(|| SmartError::NotFound("space".into()))?;
Ok(space.lower_name)
}
}
pub use crate::smart::error::SmartError as SmartServiceError;