xvc_core/root/
mod.rs

1//! Get the Xvc root directory for the current project
2use crate::error::Result;
3use crate::types::xvcroot::XvcRoot;
4use clap::Parser;
5
6use relative_path::RelativePath;
7use xvc_logging::{output, XvcOutputSender};
8
9#[derive(Debug, Parser, Clone)]
10#[command(name = "root")]
11/// Get the Xvc root directory for the current project
12pub struct RootCLI {
13    #[arg(long)]
14    /// Show absolute path instead of relative
15    absolute: bool,
16}
17
18/// Entry point for xvc root
19///
20/// # Arguments
21///
22/// - `output`: Buffer to write the result
23/// - `xvc_root`: The root of the current project
24/// - `opts`: [CLI options][RootCLI]
25///
26/// # Errors and Panics
27///
28/// - It returns an error when `output` can't be written by `writeln!`
29///   This probably leads to panic! in caller.
30/// - It returns an error when `xvc_root` cannot be converted to absolute path
31///   This should never happen if `xvc_root` properly constructed.
32pub fn run(output_snd: &XvcOutputSender, xvc_root: &XvcRoot, opts: RootCLI) -> Result<()> {
33    if opts.absolute {
34        output!("{}", xvc_root.absolute_path().to_string_lossy());
35    } else {
36        let current_dir = xvc_root.config().current_dir.option.to_path_buf();
37
38        let rel_dir = RelativePath::new(&current_dir.to_string_lossy()).relative(
39            RelativePath::new(&xvc_root.absolute_path().to_string_lossy()),
40        );
41        if rel_dir == "" {
42            output!(output_snd, ".");
43        } else {
44            output!(output_snd, "{}", rel_dir);
45        }
46    }
47    Ok(())
48}