diff --git a/src/count.rs b/src/count.rs index 4a74b27..232b013 100644 --- a/src/count.rs +++ b/src/count.rs @@ -1,27 +1,30 @@ use crate::error::Result; -use std::{fs::read_dir, path::Path, result::Result as StdResult}; +use std::{ + fs::{read_dir, ReadDir}, + iter::once, + path::Path, + result::Result as StdResult, +}; +/// The on disk layout for served repos is `//` +/// so to get the amount of repos, we just have to count everything +/// in `*/*/*` to get the count. #[instrument] -pub(crate) fn count_repositories

(repo_path: P) -> Result +pub fn count_repositories

(repo_path: P) -> Result where P: AsRef + std::fmt::Debug, { trace!("Counting repositories"); std::fs::create_dir_all(&repo_path)?; - Ok(read_dir(repo_path)? - .filter_map(StdResult::ok) - .filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false)) - .map(|entry| read_dir(entry.path())) - .filter_map(StdResult::ok) - .flat_map(|dir| { - dir.filter_map(StdResult::ok) - .filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false)) - }) - .map(|entry| read_dir(entry.path())) - .filter_map(StdResult::ok) - .flat_map(|dir| { - dir.filter_map(StdResult::ok) - .filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false)) - }) + Ok(once(read_dir(repo_path)?) + .flat_map(sub_directories) + .flat_map(sub_directories) + .flat_map(sub_directories) .count()) } + +fn sub_directories(dir: ReadDir) -> impl Iterator { + dir.filter_map(StdResult::ok) + .filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false)) + .filter_map(|entry| read_dir(entry.path()).ok()) +} diff --git a/src/error.rs b/src/error.rs index 42b7eaf..660b554 100644 --- a/src/error.rs +++ b/src/error.rs @@ -5,7 +5,7 @@ use std::fmt; pub(crate) type Result = std::result::Result; #[derive(Debug)] -pub(crate) enum Error { +pub enum Error { Badge(String), Client(reqwest::Error), Git(git2::Error), diff --git a/src/lib.rs b/src/lib.rs index 1651da7..80c273d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ extern crate tracing; mod cache; pub mod config; -mod count; +pub mod count; mod error; mod service; mod statics; diff --git a/tests/count.rs b/tests/count.rs new file mode 100644 index 0000000..709949d --- /dev/null +++ b/tests/count.rs @@ -0,0 +1,66 @@ +use hoc::count::count_repositories; + +use tempfile::TempDir; + +#[test] +fn no_repos() { + let repos = TempDir::new().unwrap(); + assert_eq!(0, count_repositories(&repos).unwrap()) +} + +#[test] +fn no_repos_for_provider() { + let repos = TempDir::new().unwrap(); + let _provider = TempDir::new_in(&repos).unwrap(); + assert_eq!(0, count_repositories(&repos).unwrap()) +} + +#[test] +fn no_repos_for_owner() { + let repos = TempDir::new().unwrap(); + let provider = TempDir::new_in(&repos).unwrap(); + let _owner = TempDir::new_in(&provider).unwrap(); + assert_eq!(0, count_repositories(&repos).unwrap()) +} + +#[test] +fn one_repo_for_owner() { + let repos = TempDir::new().unwrap(); + let provider = TempDir::new_in(&repos).unwrap(); + let owner = TempDir::new_in(&provider).unwrap(); + let _repo = TempDir::new_in(&owner).unwrap(); + assert_eq!(1, count_repositories(&repos).unwrap()) +} + +#[test] +fn two_repos_for_owner() { + let repos = TempDir::new().unwrap(); + let provider = TempDir::new_in(&repos).unwrap(); + let owner = TempDir::new_in(&provider).unwrap(); + let _repo1 = TempDir::new_in(&owner).unwrap(); + let _repo2 = TempDir::new_in(&owner).unwrap(); + assert_eq!(2, count_repositories(&repos).unwrap()) +} + +#[test] +fn two_repos_for_two_providers() { + let repos = TempDir::new().unwrap(); + let provider1 = TempDir::new_in(&repos).unwrap(); + let owner1 = TempDir::new_in(&provider1).unwrap(); + let _repo1 = TempDir::new_in(&owner1).unwrap(); + let provider2 = TempDir::new_in(&repos).unwrap(); + let owner2 = TempDir::new_in(&provider2).unwrap(); + let _repo2 = TempDir::new_in(&owner2).unwrap(); + assert_eq!(2, count_repositories(&repos).unwrap()) +} + +#[test] +fn two_subdirs_in_one_repo() { + let repos = TempDir::new().unwrap(); + let provider = TempDir::new_in(&repos).unwrap(); + let owner = TempDir::new_in(&provider).unwrap(); + let repo = TempDir::new_in(&owner).unwrap(); + let _subdir1 = TempDir::new_in(&repo).unwrap(); + let _subdir2 = TempDir::new_in(&repo).unwrap(); + assert_eq!(1, count_repositories(&repos).unwrap()) +}