diff options
author | Melody Horn <melody@boringcactus.com> | 2021-04-22 04:09:18 -0600 |
---|---|---|
committer | Melody Horn <melody@boringcactus.com> | 2021-04-22 04:09:18 -0600 |
commit | a88d3091ed0df6b4821688cca653b7fdef3a03d7 (patch) | |
tree | c0bced3aa70cf61ff8d4bb56bab565a065e9bc80 | |
parent | 8c1666c1a64201f8a12e125e3c63a83f4dbf7069 (diff) | |
download | gityeet-a88d3091ed0df6b4821688cca653b7fdef3a03d7.tar.gz gityeet-a88d3091ed0df6b4821688cca653b7fdef3a03d7.zip |
correctly find repos in subdirectories
-rw-r--r-- | src/main.rs | 2 | ||||
-rw-r--r-- | src/state.rs | 48 | ||||
-rw-r--r-- | templates/index.html | 2 |
3 files changed, 38 insertions, 14 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()) } } diff --git a/templates/index.html b/templates/index.html index 00ccd55..302c11e 100644 --- a/templates/index.html +++ b/templates/index.html @@ -11,7 +11,7 @@ <h1>hi this is gityeet</h1> <ul> {% for repo in state.data %} - <li>{{ repo.path().display() }}</li> + <li><a href="/{{ state.relative_path(repo.path()).display() }}">{{ state.relative_path(repo.path()).display() }}</a></li> {% endfor %} </ul> </body> |