feat: Clone repo when starting repo

This commit is contained in:
Paul Campbell 2024-04-23 07:09:30 +01:00
parent fc1c79620c
commit 17f5f62e61
6 changed files with 71 additions and 17 deletions

View file

@ -1,6 +1,9 @@
[webhook]
url = "https://localhost:8080/webhook"
[storage]
path = "./data"
[forge.default]
forge_type = "ForgeJo"
hostname = "git.example.net"

View file

@ -68,11 +68,26 @@ impl Actor for RepoActor {
#[derive(Message)]
#[rtype(result = "()")]
pub struct StartRepo;
impl Handler<StartRepo> for RepoActor {
pub struct CloneRepo;
impl Handler<CloneRepo> 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<LoadConfigFromRepo> 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();

View file

@ -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<GitDir> {
self.gitdir.clone().map(GitDir)
}
}
#[cfg(test)]
impl AsRef<Self> for ServerRepoConfig {
@ -327,7 +328,7 @@ pub struct RepoDetails {
pub branch: BranchName,
pub forge: ForgeDetails,
pub repo_config: Option<RepoConfig>,
pub gitdir: Option<GitDir>,
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

View file

@ -32,7 +32,7 @@ pub fn repo_details(
n: u32,
forge: ForgeDetails,
repo_config: Option<RepoConfig>,
gitdir: Option<GitDir>,
gitdir: GitDir,
) -> RepoDetails {
RepoDetails {
repo_alias: repo_alias(n),

View file

@ -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());

View file

@ -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::<Vec<_>>()
}
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)
}