diff --git a/src/crufty.rs b/src/crufty.rs index b946485..2ebf1df 100644 --- a/src/crufty.rs +++ b/src/crufty.rs @@ -1,3 +1,4 @@ +pub mod artifact_type; pub mod cleaner; pub mod cli; pub mod estimator; diff --git a/src/crufty/artifact_type.rs b/src/crufty/artifact_type.rs new file mode 100644 index 0000000..78ed9cb --- /dev/null +++ b/src/crufty/artifact_type.rs @@ -0,0 +1,21 @@ +#[derive(Debug, Clone)] +#[allow(dead_code)] +pub enum ArtifactType { + Rust, + Scala, + Custom { pattern: &'static str }, +} + +pub fn builtin() -> [ArtifactType; 2] { + [ArtifactType::Rust, ArtifactType::Scala] +} + +impl ArtifactType { + pub fn pattern(&self) -> &'static str { + match self { + ArtifactType::Rust => "**/target", + ArtifactType::Scala => "**/target", + ArtifactType::Custom { pattern } => pattern, + } + } +} diff --git a/src/crufty/fetcher.rs b/src/crufty/fetcher.rs index 249bebc..b7b9ecb 100644 --- a/src/crufty/fetcher.rs +++ b/src/crufty/fetcher.rs @@ -1,43 +1,56 @@ use std::path::PathBuf; -use globset::{Glob, GlobSetBuilder}; +use super::artifact_type::ArtifactType; +use globset::{Glob, GlobSet, GlobSetBuilder}; use walkdir::WalkDir; use super::types::ArtifactCandidate; -pub fn fetch_artifacts(root_path: &PathBuf) -> Vec { +fn mk_global_set( + artifact_types: Vec, +) -> Result { let mut builder = GlobSetBuilder::new(); - // FIX-ME hardcoded pattern for Rust - builder.add(Glob::new("**/target").unwrap()); - - let globset = builder.build().unwrap(); - - WalkDir::new(root_path) - .into_iter() - .filter_map(|entry_result| match entry_result { - Err(_) => None, - Ok(entry) if !entry.path().is_dir() => None, - Ok(entry) => { - let path = entry.into_path(); - let rel_path = path.strip_prefix(root_path).ok()?; - match globset.is_match(&rel_path) { - true => Some(ArtifactCandidate::new(path)), - false => None, + for art_type in artifact_types { + builder.add(Glob::new(art_type.pattern())?); + } + builder.build() +} + +pub fn fetch_artifacts( + root_path: &PathBuf, + artifact_types: Vec, +) -> Vec { + match mk_global_set(artifact_types) { + Err(_) => vec![], + Ok(globset) => WalkDir::new(root_path) + .into_iter() + .filter_map(|entry_result| match entry_result { + Err(_) => None, + Ok(entry) if !entry.path().is_dir() => None, + Ok(entry) => { + let path = entry.into_path(); + let rel_path = path.strip_prefix(root_path).ok()?; + match globset.is_match(&rel_path) { + true => Some(ArtifactCandidate::new(path)), + false => None, + } } - } - }) - .collect() + }) + .collect(), + } } #[cfg(test)] mod tests { - use assert_fs::prelude::*; use assert_fs::{ fixture::{ChildPath, PathChild}, + prelude::*, TempDir, }; + use crate::crufty::artifact_type::ArtifactType; + use super::{fetch_artifacts, ArtifactCandidate}; fn mk_subpath(base: &TempDir, rel_path: &str) -> ChildPath { @@ -46,6 +59,14 @@ mod tests { sub } + fn only_rust_projects() -> Vec { + vec![ArtifactType::Rust] + } + + fn custom_project(pattern: &'static str) -> Vec { + vec![ArtifactType::Custom { pattern }] + } + fn mk_rust_project(base: &P) { base.child("target").create_dir_all().unwrap(); base.child("Cargo.toml").touch().unwrap(); @@ -53,12 +74,12 @@ mod tests { #[test] fn test_simple_rust_project_being_scanned_folder() { - // given + // given there is a single rust project in the folder let temp = TempDir::new().unwrap(); mk_rust_project(&temp); - // when - let results = fetch_artifacts(&temp.to_path_buf()); + // when we search for Rust artifacts + let results = fetch_artifacts(&temp.to_path_buf(), only_rust_projects()); // then assert_eq!(results.len(), 1, "Expected exactly one artifact"); @@ -67,6 +88,12 @@ mod tests { let expected = ArtifactCandidate::new(expected_path); assert_eq!(&results[0], &expected); + // when we search for projects other than Rust + let results = + fetch_artifacts(&temp.to_path_buf(), custom_project("**/bla")); + // then + assert_eq!(results.len(), 0, "Expected zero artifacts"); + temp.close().unwrap(); } @@ -81,8 +108,9 @@ mod tests { let project3 = mk_subpath(&temp, "work/project3"); mk_rust_project(&project3); - // when - let mut results = fetch_artifacts(&temp.to_path_buf()); + // when we search for Rust artifacts + let mut results = + fetch_artifacts(&temp.to_path_buf(), only_rust_projects()); // then assert_eq!(results.len(), 3, "Expected exactly three artifacts"); @@ -107,6 +135,12 @@ mod tests { let expected_3 = ArtifactCandidate::new(expected_path_3); assert_eq!(&results[2], &expected_3); + // when we search for projects other than Rust + let results = + fetch_artifacts(&temp.to_path_buf(), custom_project("**/bla")); + // then + assert_eq!(results.len(), 0, "Expected zero artifacts"); + temp.close().unwrap(); } } diff --git a/src/main.rs b/src/main.rs index 3a7d9dd..3770293 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use clap::Parser; use console::{style, Term}; +use crufty::artifact_type; use crufty::cleaner::{self, CleanupResult}; use crufty::cli::{Cli, Commands}; use crufty::estimator::{estimate, total_size}; @@ -34,7 +35,7 @@ fn scan() -> io::Result<()> { .write_line(&format!("[+] Scanning: {}", style(path.display()).bold()))?; let spinner = ui::create_spinner("collecting artifacts"); - let mut artifacts = fetch_artifacts(&path); + let mut artifacts = fetch_artifacts(&path, artifact_type::builtin().to_vec()); spinner.finish_and_clear(); term.write_line("")?; @@ -82,7 +83,7 @@ fn clean() -> io::Result<()> { let path = env::current_dir()?; let spinner = ui::create_spinner("collecting artifacts"); - let mut artifacts = fetch_artifacts(&path); + let mut artifacts = fetch_artifacts(&path, artifact_type::builtin().to_vec()); spinner.finish_and_clear(); if artifacts.is_empty() {