find_root.rs
79 lines
| 2.2 KiB
| application/rls-services+xml
|
RustLexer
Antoine Cezar
|
r45502 | use std::path::{Path, PathBuf}; | ||
Simon Sapin
|
r47163 | /// Error type for `find_root` | ||
Antoine Cezar
|
r45502 | #[derive(Debug)] | ||
Simon Sapin
|
r47163 | pub enum FindRootError { | ||
Antoine Cezar
|
r45502 | /// Root of the repository has not been found | ||
/// Contains the current directory used by FindRoot | ||||
RootNotFound(PathBuf), | ||||
/// The current directory does not exists or permissions are insufficient | ||||
/// to get access to it | ||||
GetCurrentDirError(std::io::Error), | ||||
} | ||||
/// Find the root of the repository | ||||
Simon Sapin
|
r46751 | /// by searching for a .hg directory in the process’ current directory and its | ||
Antoine Cezar
|
r45502 | /// ancestors | ||
Simon Sapin
|
r46751 | pub fn find_root() -> Result<PathBuf, FindRootError> { | ||
Simon Sapin
|
r47163 | let current_dir = std::env::current_dir() | ||
.map_err(|e| FindRootError::GetCurrentDirError(e))?; | ||||
Simon Sapin
|
r46751 | Ok(find_root_from_path(¤t_dir)?.into()) | ||
Antoine Cezar
|
r45502 | } | ||
Simon Sapin
|
r46751 | /// Find the root of the repository | ||
/// by searching for a .hg directory in the given directory and its ancestors | ||||
pub fn find_root_from_path(start: &Path) -> Result<&Path, FindRootError> { | ||||
if start.join(".hg").exists() { | ||||
return Ok(start); | ||||
Antoine Cezar
|
r45502 | } | ||
Simon Sapin
|
r46751 | for ancestor in start.ancestors() { | ||
if ancestor.join(".hg").exists() { | ||||
return Ok(ancestor); | ||||
Antoine Cezar
|
r45502 | } | ||
} | ||||
Simon Sapin
|
r47163 | Err(FindRootError::RootNotFound(start.into())) | ||
Antoine Cezar
|
r45502 | } | ||
#[cfg(test)] | ||||
mod tests { | ||||
use super::*; | ||||
use std::fs; | ||||
use tempfile; | ||||
#[test] | ||||
fn dot_hg_not_found() { | ||||
let tmp_dir = tempfile::tempdir().unwrap(); | ||||
let path = tmp_dir.path(); | ||||
Simon Sapin
|
r46751 | let err = find_root_from_path(&path).unwrap_err(); | ||
Antoine Cezar
|
r45502 | |||
// TODO do something better | ||||
assert!(match err { | ||||
Simon Sapin
|
r47163 | FindRootError::RootNotFound(p) => p == path.to_path_buf(), | ||
_ => false, | ||||
Antoine Cezar
|
r45502 | }) | ||
} | ||||
#[test] | ||||
fn dot_hg_in_current_path() { | ||||
let tmp_dir = tempfile::tempdir().unwrap(); | ||||
let root = tmp_dir.path(); | ||||
fs::create_dir_all(root.join(".hg")).unwrap(); | ||||
Simon Sapin
|
r46751 | let result = find_root_from_path(&root).unwrap(); | ||
Antoine Cezar
|
r45502 | |||
assert_eq!(result, root) | ||||
} | ||||
#[test] | ||||
fn dot_hg_in_parent() { | ||||
let tmp_dir = tempfile::tempdir().unwrap(); | ||||
let root = tmp_dir.path(); | ||||
fs::create_dir_all(root.join(".hg")).unwrap(); | ||||
Simon Sapin
|
r46751 | let directory = root.join("some/nested/directory"); | ||
let result = find_root_from_path(&directory).unwrap(); | ||||
Antoine Cezar
|
r45502 | |||
assert_eq!(result, root) | ||||
} | ||||
} /* tests */ | ||||