vdev/utils/
paths.rs

1//! Path-related utilities
2
3use std::{
4    env,
5    fmt::Debug,
6    fs,
7    io::ErrorKind,
8    path::{Path, PathBuf},
9};
10
11use anyhow::{Context, Result};
12
13/// Find the Vector repository root by searching upward for markers like .git or Cargo.toml
14/// with a `[workspace]` section.
15pub fn find_repo_root() -> Result<PathBuf> {
16    let mut current = env::current_dir().context("Could not determine current directory")?;
17
18    loop {
19        // Check for .git directory (most reliable marker)
20        if current.join(".git").is_dir() {
21            return Ok(current);
22        }
23
24        // Check for Cargo.toml with workspace (Vector's root Cargo.toml has [workspace])
25        let cargo_toml = current.join("Cargo.toml");
26        if cargo_toml.is_file()
27            && let Ok(contents) = fs::read_to_string(&cargo_toml)
28            && contents.contains("[workspace]")
29        {
30            return Ok(current);
31        }
32
33        // Move up one directory
34        if let Some(parent) = current.parent() {
35            current = parent.to_path_buf();
36        } else {
37            anyhow::bail!(
38                "Could not find Vector repository root. Please run vdev from within the Vector repository."
39            );
40        }
41    }
42}
43
44/// Check if a path exists
45pub fn exists(path: impl AsRef<Path> + Debug) -> Result<bool> {
46    match fs::metadata(path.as_ref()) {
47        Ok(_) => Ok(true),
48        Err(error) if error.kind() == ErrorKind::NotFound => Ok(false),
49        Err(error) => Err(error).context(format!("Could not stat {path:?}")),
50    }
51}