summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Carstairs <me@joeac.net>2026-06-01 08:36:03 +0100
committerJoe Carstairs <me@joeac.net>2026-06-01 08:37:23 +0100
commit1277a0733f812fcc84a746cedb16c1317036988e (patch)
tree83a754a280ca28e4865ab448517f52cbfa6d50fe
parentc8cad70d59cc9b723b508441af119fca8b28bf92 (diff)
pull and (TODO) build and (TODO) push
-rw-r--r--src/build.rs52
-rw-r--r--src/main.rs18
2 files changed, 68 insertions, 2 deletions
diff --git a/src/build.rs b/src/build.rs
new file mode 100644
index 0000000..7f83869
--- /dev/null
+++ b/src/build.rs
@@ -0,0 +1,52 @@
+use anyhow::{Error, Result};
+use git2::BranchType;
+
+use crate::config::RepoConfig;
+
+pub fn pull_or_clone_and_build_and_push(repo: &RepoConfig) -> Result<(), BuildError> {
+ let git_repo = pull_or_clone(repo)?;
+ build(&git_repo)?;
+ push(&git_repo)?;
+
+ Ok(())
+}
+
+fn pull_or_clone(repo: &RepoConfig) -> Result<git2::Repository, BuildError> {
+ match git2::Repository::open(&repo.local_git_repo) {
+ Ok(git_repo) => {
+ pull(&git_repo).map_err(|err| BuildError::FailedToPull(err))?;
+ Ok(git_repo)
+ },
+
+ Err(open_err) => match git2::Repository::clone(&repo.remote_git_repo, &repo.local_git_repo) {
+ Ok(git_repo) => Ok(git_repo),
+ Err(clone_err) => Err(BuildError::FailedToOpenOrClone(open_err.into(), clone_err.into())),
+ }
+ }
+}
+
+fn pull(git_repo: &git2::Repository) -> Result<()> {
+ let mut origin = git_repo.find_remote("origin")?;
+ let (main_branch, main_branch_name) = git_repo.find_branch("main", BranchType::Local).map(|b| (b, "main"))
+ .or_else(|_| git_repo.find_branch("master", BranchType::Local).map(|b| (b, "master")))?;
+ let upstream_main_branch = main_branch.upstream()?;
+
+ git_repo.set_head(main_branch_name)?;
+ origin.fetch(&[main_branch_name], None, None)?;
+ let upstream_commit = git_repo.reference_to_annotated_commit(&upstream_main_branch.into_reference())?;
+ git_repo.merge(&[&upstream_commit], None, None)?;
+ Ok(())
+}
+
+fn build(git_repo: &git2::Repository) -> Result<(), BuildError> {
+ todo!()
+}
+
+fn push(git_repo: &git2::Repository) -> Result<(), BuildError> {
+ todo!()
+}
+
+pub enum BuildError {
+ FailedToOpenOrClone(Error, Error),
+ FailedToPull(Error),
+}
diff --git a/src/main.rs b/src/main.rs
index 215f9e6..42cfaae 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,12 +4,13 @@ use dirs::config_dir;
#[macro_use] extern crate rocket;
+mod build;
mod config;
use config::read_config;
use rocket::{State, http::Status};
-use crate::config::Config;
+use crate::{build::{BuildError, pull_or_clone_and_build_and_push}, config::Config};
const BIN_NAME: &str = "build-joeac";
@@ -30,7 +31,20 @@ fn index(remote_git_repo: PathBuf, config: &State<Config>) -> (Status, String) {
None => (Status::BadRequest, format!("Failed to convert request path to unicode: {:?}", remote_git_repo)),
Some(remote_git_repo) => match config.repositories.iter().find(|repo| repo.remote_git_repo.eq(remote_git_repo)) {
None => (Status::NotFound, format!("Remote git repository not configured: {remote_git_repo}")),
- Some(repo) => (Status::Ok, format!("Matched! {:?}", repo))
+ Some(repo) => match pull_or_clone_and_build_and_push(repo) {
+ Err(BuildError::FailedToOpenOrClone(open_err, clone_err)) => (
+ Status::InternalServerError,
+ format!(
+ "Failed to open or clone git repository. Error opening: {:#?}\n\nError cloning: {:#?}",
+ open_err,
+ clone_err)
+ ),
+ Err(BuildError::FailedToPull(err)) => (
+ Status::InternalServerError,
+ format!("Failed to pull git repository. Error: {:#?}", err),
+ ),
+ Ok(()) => (Status::Ok, String::from("Pulled, built and pushed image")),
+ }
}
}
}