Skip to content

Commit

Permalink
Extract use files
Browse files Browse the repository at this point in the history
  • Loading branch information
paudrow committed Feb 19, 2024
1 parent b4c30a7 commit 8efbf88
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 62 deletions.
24 changes: 19 additions & 5 deletions src/yatm_v2/src/app/cli.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
use crate::app::constants::YAML_EXTENSIONS;
use crate::app::load_config::load_config;
use crate::app::requirements::get_requirements_from_files;
use crate::app::{
init_workspace::init_workspace,
requirements::{
get_requirements_from_file, validate_requirements_file, validate_requirements_files,
},
};
use crate::types::{RequirementsFile, TestCasesBuilderFile};
use crate::utils::get_files;

use std::path::PathBuf;

use anyhow::{Context, Ok, Result};
use clap::{Parser, Subcommand};

use super::requirements::get_requirements_files;

// Define the main application
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
Expand Down Expand Up @@ -170,7 +169,7 @@ pub fn cli() -> Result<()> {
}
RequirementsSubcommands::List { config_path } => {
let config = load_config(&config_path)?;
let requirements_files = get_requirements_files(&config.requirements_dirs)?;
let requirements_files = get_files(&config.requirements_dirs, &YAML_EXTENSIONS)?;
for requirement_file in requirements_files {
println!(
"{}",
Expand Down Expand Up @@ -285,7 +284,7 @@ mod test_cli {
}

#[test]
fn full_requirements_test() {
fn test_init() {
let dir = tempdir().unwrap().path().to_path_buf();

// run the init command
Expand All @@ -305,6 +304,21 @@ mod test_cli {
assert!(config.generated_files_dir.is_dir());
assert!(dir.join(".gitignore").is_file());
assert_eq!(get_number_of_files_in_dir(&config.new_requirements_dir), 1);
}

#[test]
fn test_requirements() {
let dir = tempdir().unwrap().path().to_path_buf();

// run the init command
let mut cmd = get_command();
cmd.args(&["init", "--path", dir.to_str().unwrap()])
.assert()
.success();

// load the config
assert!(dir.join("config.yaml").is_file());
let config = load_config(&dir).unwrap();

// run the requirements new command
let new_requirements_file_name = "my-test-requirements.yaml";
Expand Down
1 change: 1 addition & 0 deletions src/yatm_v2/src/app/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub const YAML_EXTENSIONS: [&str; 2] = ["yaml", "yml"];
1 change: 1 addition & 0 deletions src/yatm_v2/src/app/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod cli;
mod constants;
mod init_workspace;
mod load_config;
mod requirements;
Expand Down
90 changes: 33 additions & 57 deletions src/yatm_v2/src/app/requirements.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::app::constants::YAML_EXTENSIONS;
use crate::types::RequirementsFile;
use crate::utils::get_files;
use anyhow::{Context, Result};
use common::types::Requirement;
use serde_yaml;
Expand All @@ -16,63 +18,6 @@ pub fn validate_requirements_file(requirement_path: &PathBuf) -> Result<()> {
Ok(())
}

/// Get the requirements from the files.
pub fn get_requirements_from_files(requirement_dirs: &Vec<PathBuf>) -> Result<Vec<Requirement>> {
let requirement_files = get_requirements_files(&requirement_dirs).context(format!(
"Failed to get the requirement files: {:?}",
requirement_dirs
))?;
let mut all_requirements: Vec<Requirement> = vec![];
for requirement_file in requirement_files {
let requirements = get_requirements_from_file(&requirement_file).context(format!(
"Failed to validate the requirement: {:?}",
requirement_file
))?;
all_requirements.extend(requirements);
}
Ok(all_requirements)
}

/// Get the requirements from a file.
pub fn get_requirements_from_file(requirement_path: &PathBuf) -> Result<Vec<Requirement>> {
let requirement = std::fs::read_to_string(&requirement_path).context(format!(
"Failed to read the requirement file: {:?}",
requirement_path
))?;
let requirements_file =
serde_yaml::from_str::<RequirementsFile>(&requirement).context(format!(
"Failed to deserialize the requirement: {:?}",
requirement_path
))?;
Ok(requirements_file.requirements)
}

/// Get the requirements file paths.
pub fn get_requirements_files(requirement_dirs: &Vec<PathBuf>) -> Result<Vec<PathBuf>> {
let mut requirements_files: Vec<PathBuf> = vec![];
for requirement_dir in requirement_dirs {
let requirement_files = std::fs::read_dir(&requirement_dir).context(format!(
"Failed to read the requirement directory: {:?}",
requirement_dir
))?;
for requirement_file in requirement_files {
let requirement_file = requirement_file.context(format!(
"Failed to read the entry in the requirement directory: {:?}",
requirement_dir
))?;
let requirement_path = requirement_file.path();
requirements_files.push(requirement_path);
}
}
if requirements_files.is_empty() {
return Err(anyhow::anyhow!(format!(
"No requirement files found: {:#?}",
requirement_dirs
)));
}
Ok(requirements_files)
}

#[cfg(test)]
mod test_validate_requirement {
use super::*;
Expand Down Expand Up @@ -111,3 +56,34 @@ mod test_validate_requirement {
assert!(validate_requirements_file(&requirement_path).is_err());
}
}

/// Get the requirements from the files.
pub fn get_requirements_from_files(requirement_dirs: &Vec<PathBuf>) -> Result<Vec<Requirement>> {
let requirement_files = get_files(&requirement_dirs, &YAML_EXTENSIONS).context(format!(
"Failed to get the requirement files: {:?}",
requirement_dirs
))?;
let mut all_requirements: Vec<Requirement> = vec![];
for requirement_file in requirement_files {
let requirements = get_requirements_from_file(&requirement_file).context(format!(
"Failed to validate the requirement: {:?}",
requirement_file
))?;
all_requirements.extend(requirements);
}
Ok(all_requirements)
}

/// Get the requirements from a file.
pub fn get_requirements_from_file(requirement_path: &PathBuf) -> Result<Vec<Requirement>> {
let requirement = std::fs::read_to_string(&requirement_path).context(format!(
"Failed to read the requirement file: {:?}",
requirement_path
))?;
let requirements_file =
serde_yaml::from_str::<RequirementsFile>(&requirement).context(format!(
"Failed to deserialize the requirement: {:?}",
requirement_path
))?;
Ok(requirements_file.requirements)
}
1 change: 1 addition & 0 deletions src/yatm_v2/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod app;
mod github;
mod test_cases;
mod types;
mod utils;

use anyhow::{Context, Ok, Result};
use types::LocalIssue;
Expand Down
101 changes: 101 additions & 0 deletions src/yatm_v2/src/utils/get_files.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use anyhow::{Context, Result};
use std::path::PathBuf;

/// Get the files with the given extensions recursively from the directories.
pub fn get_files(dir: &Vec<PathBuf>, extensions: &[&str]) -> Result<Vec<PathBuf>> {
// Recursively called helper function to process directories
fn get_files_recursive(
dir: &PathBuf,
extensions: &[&str],
out_files: &mut Vec<PathBuf>,
) -> Result<()> {
let paths = std::fs::read_dir(dir)
.with_context(|| format!("Failed to read the directory: {:?}", dir))?;
for path in paths {
let entry = path
.with_context(|| format!("Failed to read the entry in the directory: {:?}", dir))?;
let file_path = entry.path();
if file_path.is_dir() {
// If the path is a directory, recursively search it
get_files_recursive(&file_path, extensions, out_files)?;
} else {
// Otherwise, process the file
let extension = file_path
.extension()
.and_then(|e| e.to_str())
.map(|e| e.to_lowercase());
if let Some(extension) = extension {
if extensions.contains(&extension.as_str()) {
out_files.push(file_path);
}
}
}
}
Ok(())
}

let mut out_files: Vec<PathBuf> = vec![];
for dir in dir {
get_files_recursive(dir, extensions, &mut out_files)?;
}
if out_files.is_empty() {
return Err(anyhow::anyhow!("No files found in directory: {:?}", dir));
}
Ok(out_files)
}

#[cfg(test)]
mod test_get_files {
use super::*;
use std::fs::File;
use std::io::Write;
use tempfile::tempdir;

const YAML_EXTENSIONS: [&str; 1] = ["yaml"];

#[test]
fn test_get_files() {
let dir = tempdir().unwrap();
let file_path = dir.path().join("file.yaml");
let mut file = File::create(&file_path).unwrap();
let file_str = "file";
file.write_all(file_str.as_bytes()).unwrap();
let files = get_files(&vec![dir.path().to_path_buf()], &YAML_EXTENSIONS).unwrap();
assert_eq!(files.len(), 1);
assert_eq!(files[0], file_path);
}

#[test]
fn test_get_files_invalid() {
let dir = tempdir().unwrap();
let files = get_files(&vec![dir.path().to_path_buf()], &YAML_EXTENSIONS);
assert!(files.is_err());
}

#[test]
fn test_get_files_recursive() {
let dir = tempdir().unwrap();
let sub_dir = dir.path().join("sub_dir");
std::fs::create_dir(&sub_dir).unwrap();
let file_path = sub_dir.join("file.yaml");
let mut file = File::create(&file_path).unwrap();
let file_str = "file";
file.write_all(file_str.as_bytes()).unwrap();
let files = get_files(&vec![dir.path().to_path_buf()], &YAML_EXTENSIONS).unwrap();
assert_eq!(files.len(), 1);
assert_eq!(files[0], file_path);
}

#[test]
fn test_get_files_recursive_invalid() {
let dir = tempdir().unwrap();
let sub_dir = dir.path().join("sub_dir");
std::fs::create_dir(&sub_dir).unwrap();
let file_path = sub_dir.join("file.txt");
let mut file = File::create(&file_path).unwrap();
let file_str = "file";
file.write_all(file_str.as_bytes()).unwrap();
let files = get_files(&vec![dir.path().to_path_buf()], &YAML_EXTENSIONS);
assert!(files.is_err());
}
}
3 changes: 3 additions & 0 deletions src/yatm_v2/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod get_files;

pub use get_files::get_files;

0 comments on commit 8efbf88

Please sign in to comment.