diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 2 | ||||
-rw-r--r-- | src/state.rs | 48 |
2 files changed, 37 insertions, 13 deletions
diff --git a/src/main.rs b/src/main.rs index 52dcaee..795cf41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,6 +34,8 @@ async fn main() -> Result<()> { // TODO do something smarter for that let mut app = tide::with_state(Arc::new(Mutex::new(state))); app.at("/").get(index); + app.at("/*repo").get(|_| async { Ok("bruh") }); + app.at("/*repo/tree").get(|_| async { Ok("bruh tree") }); app.listen(("127.0.0.1", port)).await?; Ok(()) } diff --git a/src/state.rs b/src/state.rs index 1a88929..475302b 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,24 +1,46 @@ -use std::io; -use std::path::Path; - -use async_std::prelude::*; -use async_std::fs::read_dir; +use std::fs::read_dir; +use std::path::{Path, PathBuf}; +use eyre::Result; use git2::Repository; pub struct State { + pub root: PathBuf, pub data: Vec<Repository>, } +// TODO figure out how to make this return impl Stream without living in actual hell +// Heartbreaking: E0733 +fn find_repos_in(dir: impl AsRef<Path>) -> Result<Vec<Repository>> { + let dir = dir.as_ref(); + let dir = read_dir(dir)?; + let mut result = vec![]; + for subdir in dir { + match subdir { + Ok(subdir) => { + match Repository::open_bare(subdir.path()) { + Ok(repo) => result.push(repo), + Err(err) if err.class() == git2::ErrorClass::Repository && err.code() == git2::ErrorCode::NotFound => { + result.extend(find_repos_in(subdir.path())?) + } + // TODO handle in a non-god-awful way + Err(err) => panic!("{}", err), + } + } + Err(_) => {}, + } + } + Ok(result) +} + impl State { - pub async fn discover(root: impl AsRef<Path>) -> io::Result<Self> { + pub async fn discover(root: impl AsRef<Path>) -> Result<Self> { let root = root.as_ref(); - let dir = read_dir(root).await?; - let data = dir - .filter_map(|subdir| { - subdir.ok().and_then(|subdir| Repository::open_bare(&subdir.path()).ok()) - }) - .collect().await; - Ok(Self { data }) + let data = find_repos_in(root)?; + Ok(Self { root: root.to_owned(), data }) + } + + pub fn relative_path<'a>(&'a self, subdir: &'a Path) -> &'a Path { + subdir.strip_prefix(&self.root).unwrap_or_else(|_| subdir.as_ref()) } } |