summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build.rs52
-rw-r--r--src/config.rs24
-rw-r--r--src/main.rs52
-rw-r--r--src/routes.rs37
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())
+ }
+}