From d8be78d018778eafe37b1c450dfeef3078de252e Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Fri, 27 Jan 2023 17:29:24 +0800 Subject: [PATCH] allow choosing filename --- src/lib.rs | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f818c56..122d638 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,9 +5,9 @@ use std::ffi::OsString; use std::fs::read_dir; +use std::io::ErrorKind; use std::path::PathBuf; use std::{env, io}; -use std::io::ErrorKind; /// Get the project root (relative to closest Cargo.lock file) /// ```rust @@ -17,25 +17,37 @@ use std::io::ErrorKind; /// }; /// ``` pub fn get_project_root() -> io::Result { + get_project_root_using("Cargo.lock".to_string()) +} + +/// Get the project root relative to specified file. +/// ```rust +/// match project_root::get_project_root_using("Makefile.toml".to_string()) { +/// Ok(p) => println!("Current project root is {:?}", p), +/// Err(e) => println!("Error obtaining project root {:?}", e) +/// }; +/// ``` +pub fn get_project_root_using(filename: String) -> io::Result { let path = env::current_dir()?; - let mut path_ancestors = path.as_path().ancestors(); + let path_ancestors = path.as_path().ancestors(); - while let Some(p) = path_ancestors.next() { - let has_cargo = - read_dir(p)? - .into_iter() - .any(|p| p.unwrap().file_name() == OsString::from("Cargo.lock")); + for p in path_ancestors { + let has_cargo = read_dir(p)? + .into_iter() + .any(|p| p.unwrap().file_name() == OsString::from(filename.clone())); if has_cargo { - return Ok(PathBuf::from(p)) + return Ok(PathBuf::from(p)); } } - Err(io::Error::new(ErrorKind::NotFound, "Ran out of places to find Cargo.toml")) - + Err(io::Error::new( + ErrorKind::NotFound, + format!("Ran out of places to find {}", filename), + )) } #[cfg(test)] mod tests { - use crate::get_project_root; + use crate::*; use std::fs::read_to_string; #[test] @@ -49,4 +61,17 @@ mod tests { assert!(toml_string.contains(crate_name)); } + + #[test] + fn it_should_find_our_project_root_using_readme() { + let crate_name = "name = \"project-root\""; + + let project_root = + get_project_root_using("README.md".to_string()).expect("There is no project root"); + + let toml_path = project_root.to_str().unwrap().to_owned() + "/Cargo.toml"; + let toml_string = read_to_string(toml_path).unwrap(); + + assert!(toml_string.contains(crate_name)); + } }