Merge pull request #478 from Masynchin/count
Some checks failed
continuous-integration/drone/push Build is failing

Refactor count_repositories
This commit is contained in:
Valentin Brandl 2022-08-22 15:34:32 +02:00 committed by GitHub
commit 6c7cb9df97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 88 additions and 19 deletions

View File

@ -1,27 +1,30 @@
use crate::error::Result; 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 `<service>/<user>/<repo>`
/// so to get the amount of repos, we just have to count everything
/// in `*/*/*` to get the count.
#[instrument] #[instrument]
pub(crate) fn count_repositories<P>(repo_path: P) -> Result<usize> pub fn count_repositories<P>(repo_path: P) -> Result<usize>
where where
P: AsRef<Path> + std::fmt::Debug, P: AsRef<Path> + std::fmt::Debug,
{ {
trace!("Counting repositories"); trace!("Counting repositories");
std::fs::create_dir_all(&repo_path)?; std::fs::create_dir_all(&repo_path)?;
Ok(read_dir(repo_path)? Ok(once(read_dir(repo_path)?)
.filter_map(StdResult::ok) .flat_map(sub_directories)
.filter(|entry| entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false)) .flat_map(sub_directories)
.map(|entry| read_dir(entry.path())) .flat_map(sub_directories)
.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))
})
.count()) .count())
} }
fn sub_directories(dir: ReadDir) -> impl Iterator<Item = ReadDir> {
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())
}

View File

@ -5,7 +5,7 @@ use std::fmt;
pub(crate) type Result<T> = std::result::Result<T, Error>; pub(crate) type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum Error { pub enum Error {
Badge(String), Badge(String),
Client(reqwest::Error), Client(reqwest::Error),
Git(git2::Error), Git(git2::Error),

View File

@ -11,7 +11,7 @@ extern crate tracing;
mod cache; mod cache;
pub mod config; pub mod config;
mod count; pub mod count;
mod error; mod error;
mod service; mod service;
mod statics; mod statics;

66
tests/count.rs Normal file
View File

@ -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())
}