Skip to main content

open_kioku_git/
lib.rs

1use open_kioku_errors::{OkError, Result};
2use std::fs;
3use std::path::{Path, PathBuf};
4
5pub fn discover_root(start: impl AsRef<Path>) -> Result<PathBuf> {
6    let mut current = start.as_ref().canonicalize()?;
7    loop {
8        if current.join(".git").exists() || current.join("ok.toml").exists() {
9            return Ok(current);
10        }
11        if !current.pop() {
12            return Ok(start.as_ref().canonicalize()?);
13        }
14    }
15}
16
17pub fn branch(root: impl AsRef<Path>) -> Option<String> {
18    let head = fs::read_to_string(root.as_ref().join(".git/HEAD")).ok()?;
19    if let Some(value) = head.strip_prefix("ref: refs/heads/") {
20        return Some(value.trim().to_string());
21    }
22    None
23}
24
25pub fn commit(root: impl AsRef<Path>) -> Option<String> {
26    let head = fs::read_to_string(root.as_ref().join(".git/HEAD")).ok()?;
27    if !head.starts_with("ref: ") {
28        return Some(head.trim().to_string());
29    }
30    let reference = head.trim().strip_prefix("ref: ")?;
31    fs::read_to_string(root.as_ref().join(".git").join(reference))
32        .ok()
33        .map(|value| value.trim().to_string())
34}
35
36pub fn require_repo(root: impl AsRef<Path>) -> Result<PathBuf> {
37    let root = discover_root(root)?;
38    if !root.exists() {
39        return Err(OkError::Repository(format!(
40            "repository root does not exist: {}",
41            root.display()
42        )));
43    }
44    Ok(root)
45}