diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/build.rs | 52 | ||||
| -rw-r--r-- | src/config.rs | 24 | ||||
| -rw-r--r-- | src/main.rs | 52 | ||||
| -rw-r--r-- | src/routes.rs | 37 |
4 files changed, 57 insertions, 108 deletions
diff --git a/src/build.rs b/src/build.rs deleted file mode 100644 index 7f83869..0000000 --- a/src/build.rs +++ /dev/null @@ -1,52 +0,0 @@ -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/config.rs b/src/config.rs deleted file mode 100644 index 5d17bfc..0000000 --- a/src/config.rs +++ /dev/null @@ -1,24 +0,0 @@ -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, -} diff --git a/src/main.rs b/src/main.rs index 42cfaae..5dd5db5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,47 +4,35 @@ use dirs::config_dir; #[macro_use] extern crate rocket; -mod build; -mod config; +mod routes; -use config::read_config; +use anyhow::Result; +use routes::read_routes; 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]) + let routes_path: PathBuf = config_dir().unwrap().join(BIN_NAME).join("routes"); + let routes = read_routes(&routes_path).expect("Failed to read routes config"); + rocket::build().manage(routes).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, built and pushed image")), - } +#[get("/<req_path..>")] +fn index(req_path: PathBuf, routes: &State<Vec<String>>) -> (Status, String) { + match req_path.to_str().map(String::from) { + None => (Status::BadRequest, format!("Failed to convert request path to unicode: {:?}", req_path)), + Some(req_path) => match routes.iter().find(|&route| req_path.eq(route)) { + None => (Status::NotFound, format!("Route not configured: {req_path}")), + Some(route) => match execute_route(route) { + Ok(_) => todo!(), + Err(_) => todo!(), + }, } } } + +fn execute_route(route: &str) -> Result<()> { + todo!(); +} diff --git a/src/routes.rs b/src/routes.rs new file mode 100644 index 0000000..9a1e401 --- /dev/null +++ b/src/routes.rs @@ -0,0 +1,37 @@ +use anyhow::anyhow; +use anyhow::Result; +use is_executable::is_executable; +use std::fs::DirEntry; +use std::fs::metadata; +use std::{fs::read_dir, path::PathBuf}; + +pub fn read_routes(path: &PathBuf) -> Result<Vec<String>> { + read_routes_with_prefix(path, "/") +} + +fn read_routes_with_prefix(path: &PathBuf, prefix: &str) -> Result<Vec<String>> { + Ok( + read_dir(path)? + .map(|entry| read_entry_with_prefix(&entry?, path, prefix)) + .flatten().flatten().collect()) +} + +fn read_entry_with_prefix(entry: &DirEntry, dir_path: &PathBuf, prefix: &str) -> Result<Vec<String>> { + let entry_path = entry.path(); + let metadata = metadata(&entry_path)?; + if metadata.is_dir() { + let entry_basename = entry_path.file_name() + .ok_or(anyhow!("No basename for file: {:?} in directory: {:?}", entry_path, dir_path))?; + let result = read_routes_with_prefix(&entry_path, &format!("{prefix}{:?}/", entry_basename)); + result + } else if metadata.is_file() { + if !is_executable(entry.path()) { + eprintln!("Found {:?} in routes config directory, but cannot configure route as the file is not executable", entry); + return Ok(Vec::new()); + } + Ok(vec![format!("{:?}", entry_path)]) + } else { + eprintln!("Found {:?} in routes config directory, but cannot configure route as the file is neither a directory nor an ordinary file", entry); + Ok(Vec::new()) + } +} |
