From a88d3091ed0df6b4821688cca653b7fdef3a03d7 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Thu, 22 Apr 2021 04:09:18 -0600 Subject: correctly find repos in subdirectories --- src/main.rs | 2 ++ src/state.rs | 48 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 13 deletions(-) (limited to 'src') 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, } +// TODO figure out how to make this return impl Stream without living in actual hell +// Heartbreaking: E0733 +fn find_repos_in(dir: impl AsRef) -> Result> { + 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) -> io::Result { + pub async fn discover(root: impl AsRef) -> Result { 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()) } } -- cgit v1.2.3