Compare commits
5 Commits
8585cac606
...
3ee4cc6dc4
| Author | SHA1 | Date | |
|---|---|---|---|
| 3ee4cc6dc4 | |||
| c8cad70d59 | |||
| f849de20bb | |||
| 2068342144 | |||
| e433feddbe |
Generated
+2211
File diff suppressed because it is too large
Load Diff
@@ -4,3 +4,9 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.102"
|
||||
dirs = "6.0.0"
|
||||
git2 = "0.20.4"
|
||||
rocket = "0.5.1"
|
||||
serde = "1.0.228"
|
||||
toml = "1.1.2"
|
||||
|
||||
@@ -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 build(git_repo: &git2::Repository) -> Result<(), BuildError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn push(git_repo: &git2::Repository) -> Result<(), BuildError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
pub enum BuildError {
|
||||
FailedToOpenOrClone(Error, Error),
|
||||
FailedToPull(Error),
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Context;
|
||||
use serde::Deserialize;
|
||||
|
||||
pub fn read_config(path: &PathBuf) -> anyhow::Result<Config> {
|
||||
let toml = std::fs::read(path)
|
||||
.with_context(|| format!("Failed to read config file at {:#?}", path))?;
|
||||
let config = toml::from_slice(&toml)
|
||||
.with_context(|| format!("Failed to parse config file at {:#?}", path))?;
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct Config {
|
||||
pub repositories: Vec<RepoConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct RepoConfig {
|
||||
pub remote_git_repo: String,
|
||||
pub local_git_repo: String,
|
||||
pub remote_package_repo: String,
|
||||
}
|
||||
+49
-2
@@ -1,3 +1,50 @@
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
use std::path::PathBuf;
|
||||
|
||||
use dirs::config_dir;
|
||||
|
||||
#[macro_use] extern crate rocket;
|
||||
|
||||
mod build;
|
||||
mod config;
|
||||
|
||||
use config::read_config;
|
||||
use rocket::{State, http::Status};
|
||||
|
||||
use crate::{build::{BuildError, pull_or_clone_and_build_and_push}, config::Config};
|
||||
|
||||
const BIN_NAME: &str = "build-joeac";
|
||||
|
||||
#[launch]
|
||||
fn rocket() -> _ {
|
||||
let config_path: PathBuf = config_dir().unwrap()
|
||||
.join(BIN_NAME).join(BIN_NAME).with_added_extension("toml");
|
||||
let config = read_config(&config_path).inspect_err(|err|
|
||||
eprintln!("Failed to read config. Error: {}\nProceeding with defaults", err))
|
||||
.unwrap_or(Config::default());
|
||||
|
||||
rocket::build().manage(config).mount("/", routes![index])
|
||||
}
|
||||
|
||||
#[get("/<remote_git_repo..>")]
|
||||
fn index(remote_git_repo: PathBuf, config: &State<Config>) -> (Status, String) {
|
||||
match remote_git_repo.to_str() {
|
||||
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) => 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 git repository, now building and pushing")),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user