use std::path::PathBuf;
use super::OrchestrationError;
use systemprompt_config::SecretsBootstrap;
use systemprompt_identifiers::{ManagedSourceId, UserId};
use systemprompt_marketplace::managed::{
GitSyncRequest, GitSyncResult, ManagedRepository, SourceSpec,
};
#[derive(Debug, Clone)]
pub struct GitSourceOrchestrator {
managed: ManagedRepository,
scratch_root: PathBuf,
}
impl GitSourceOrchestrator {
pub const fn new(managed: ManagedRepository, scratch_root: PathBuf) -> Self {
Self {
managed,
scratch_root,
}
}
pub async fn synchronize(
&self,
owner: &UserId,
request: &GitSyncRequest,
) -> Result<GitSyncResult, OrchestrationError> {
let credential = self.credential(owner, &request.source_id).await?;
Ok(self
.managed
.sync_git_source_with_credential(
owner,
request,
credential.as_deref(),
&self.scratch_root,
)
.await?)
}
async fn credential(
&self,
owner: &UserId,
source: &ManagedSourceId,
) -> Result<Option<String>, OrchestrationError> {
match self.managed.get_source(owner, source).await? {
SourceSpec::Git {
credential_reference: Some(reference),
..
} => {
let secrets =
SecretsBootstrap::get().map_err(OrchestrationError::CredentialsUnavailable)?;
let credential = secrets
.get(&reference)
.filter(|value| !value.is_empty())
.ok_or(OrchestrationError::CredentialUnresolved)?;
Ok(Some(credential.clone()))
},
SourceSpec::Git {
credential_reference: None,
..
} => Ok(None),
_ => Err(OrchestrationError::NotGitSource),
}
}
}