relay-knowledge 1.1.14

Graph-database-based knowledge graph project.
Documentation
use std::path::Path;

use crate::code::{
    CodeIndexError,
    source::{
        git::{git_bytes, resolve_ref},
        gitlink as source_gitlink,
    },
};

pub(super) enum StagedPathKind {
    Gitlink(String),
    Regular,
}

pub(super) fn staged_path_kind(
    root: &Path,
    path: &str,
) -> Result<Option<StagedPathKind>, CodeIndexError> {
    let bytes = git_bytes(root, ["ls-files", "-s", "-z", "--", path])?;
    let Some(record) = bytes
        .split(|byte| *byte == 0)
        .find(|record| !record.is_empty())
    else {
        return Ok(None);
    };
    let record = String::from_utf8_lossy(record);
    let Some((metadata, _)) = record.split_once('\t') else {
        return Ok(None);
    };
    let fields = metadata.split_whitespace().collect::<Vec<_>>();
    if fields.first().copied() != Some("160000") {
        return Ok(Some(StagedPathKind::Regular));
    }

    Ok(fields
        .get(1)
        .map(|object| StagedPathKind::Gitlink((*object).to_owned())))
}

pub(super) fn submodule_worktree_parent_path(parent_path: &str, child_path: &str) -> String {
    format!("{}/{}", parent_path.trim_end_matches('/'), child_path)
}

pub(super) fn submodule_worktree_head(
    root: &Path,
    path: &str,
) -> Result<Option<String>, CodeIndexError> {
    let submodule_root = match source_gitlink::submodule_root(root, path) {
        Ok(submodule_root) => submodule_root,
        Err(_) => return Ok(None),
    };

    resolve_ref(&submodule_root, "HEAD").map(Some)
}

pub(super) fn base_path_exists(
    root: &Path,
    base_commit: &str,
    path: &str,
) -> Result<bool, CodeIndexError> {
    git_object_kind(root, base_commit, path).map(|kind| kind.is_some())
}

fn git_object_kind(
    root: &Path,
    commit: &str,
    path: &str,
) -> Result<Option<String>, CodeIndexError> {
    match git_bytes(root, ["cat-file", "-t", &format!("{commit}:{path}")]) {
        Ok(bytes) => Ok(Some(String::from_utf8_lossy(&bytes).trim().to_owned())),
        Err(_) => Ok(None),
    }
}

#[cfg(test)]
#[path = "state_tests.rs"]
mod tests;