//! `internal/meta` on the forge: the repo the swarm meta flake is committed to //! (`crate::meta_flake`), and the read grant each hive's account holds on it. use anyhow::{Context, Result}; use base64::Engine as _; use forgejo_api::structs::{ AddCollaboratorOptionPermission, ChangeFileOperation, ChangeFileOperationOperation, ChangeFilesOptions, }; use super::objects::SHARED_ORG; use super::{Client, DefaultBranchFiles}; use crate::meta_flake::{META_REPO, MetaFile, MetaForge}; impl MetaForge for Client { async fn head_files( &self, owner: &str, repo: &str, paths: &[&str], ) -> Result> { self.default_branch_files(owner, repo, paths).await } async fn ensure_meta_repo(&self) -> Result<()> { self.create_shared_repo(SHARED_ORG, META_REPO, true).await } async fn grant_meta_read(&self, login: &str) -> Result<()> { self.add_collaborator_to( SHARED_ORG, META_REPO, login, AddCollaboratorOptionPermission::Read, ) .await } async fn commit_meta(&self, message: &str, files: Vec) -> Result<()> { let ops: Vec = files .into_iter() .map(|f| ChangeFileOperation { content: Some(base64::engine::general_purpose::STANDARD.encode(f.bytes)), from_path: None, operation: if f.sha.is_some() { ChangeFileOperationOperation::Update } else { ChangeFileOperationOperation::Create }, path: f.path.to_owned(), sha: f.sha, }) .collect(); self.api .call(|api| { api.repo_change_files( SHARED_ORG, META_REPO, ChangeFilesOptions { author: None, branch: None, committer: None, dates: None, files: ops.clone(), force_overwrite_new_branch: None, message: Some(message.to_owned()), new_branch: None, signoff: None, }, ) .into_future() }) .await .with_context(|| format!("commit to {SHARED_ORG}/{META_REPO}"))?; Ok(()) } }