1use crate::{constants, errors};
2
3pub fn current_dir() -> std::path::PathBuf {
5 std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from(constants::DOT))
6}
7
8pub(crate) fn current_dir_string() -> String {
10 current_dir().to_string_lossy().to_string()
11}
12
13pub(crate) fn home_dir() -> std::path::PathBuf {
15 dirs::home_dir().unwrap_or_else(|| std::path::PathBuf::from("/tmp"))
16}
17
18pub(crate) fn canonicalize<P: AsRef<std::path::Path>>(
20 path: P,
21) -> std::io::Result<std::path::PathBuf> {
22 dunce::canonicalize(path)
23}
24
25pub fn abspath<P: AsRef<std::path::Path> + std::marker::Copy>(path: P) -> std::path::PathBuf {
27 canonicalize(path).unwrap_or(path.as_ref().to_path_buf())
28}
29
30pub(crate) fn str_basename(path: &str) -> &str {
32 let basename = if path.contains('/') {
33 path.split('/').next_back().unwrap_or(path)
34 } else if path.contains('\\') {
35 path.split('\\').next_back().unwrap_or(path)
36 } else {
37 path
38 };
39
40 basename
41}
42
43pub(crate) fn is_shell(basename: &str) -> bool {
45 matches!(
46 basename,
47 constants::SHELL_BASH
48 | constants::SHELL_DASH
49 | constants::SHELL_KSH
50 | constants::SHELL_SH
51 | constants::SHELL_ZSH
52 )
53}
54
55pub(crate) fn strip_prefix(
57 root: &std::path::Path,
58 path: &std::path::Path,
59) -> Result<std::path::PathBuf, errors::GardenError> {
60 let stripped_path = if path.starts_with(root) {
61 path.strip_prefix(root)
63 .map_err(|err| {
64 errors::GardenError::ConfigurationError(format!(
65 "{path:?} is not a child of {root:?}: {err:?}"
66 ))
67 })?
68 .to_path_buf()
69 } else {
70 path.to_path_buf()
71 };
72
73 Ok(stripped_path)
74}
75
76pub(crate) fn strip_prefix_into_string(
78 root: &std::path::Path,
79 path: &std::path::Path,
80) -> Result<String, errors::GardenError> {
81 let path_str = strip_prefix(root, path)?.to_string_lossy().to_string();
82 Ok(path_str)
83}