Skip to main content

eska_tool_runtime/
vcs.rs

1//! Small typed calls to the VCS owner's private protocol, without a repository implementation.
2
3use crate::{Component, Error, query};
4use std::{ffi::OsString, path::Path};
5
6/// Recheck only selected source paths using the same preflighted executable throughout a transaction.
7///
8/// # Errors
9/// Returns cancellation, repository failures and invalid counts without claiming a clean source.
10pub fn source_changes(
11    binary: &Path,
12    root: &Path,
13    empty: bool,
14    files: usize,
15) -> Result<usize, Error> {
16    let mut options = vec![OsString::from("--files"), OsString::from(files.to_string())];
17    if empty {
18        options.push(OsString::from("--empty-scaffold"));
19    }
20    query(Component::Vcs, binary, "source_changes", root, &options)?
21        .get("local_changes")
22        .and_then(serde_json::Value::as_u64)
23        .and_then(|count| usize::try_from(count).ok())
24        .ok_or(Error::InvalidResponse)
25}
26
27/// Inspect the nearest on-disk repository before the caller starts a file transaction.
28///
29/// # Errors
30/// Preserves component, malformed-response and repository failures instead of claiming absence.
31pub fn exists(binary: &Path, root: &Path) -> Result<bool, Error> {
32    query(Component::Vcs, binary, "repository_exists", root, &[])?
33        .get("exists")
34        .and_then(serde_json::Value::as_bool)
35        .ok_or(Error::InvalidResponse)
36}
37
38/// Initialize Git inside a newly claimed project; the caller owns rollback of that directory.
39///
40/// # Errors
41/// Rejects existing metadata, component failures and incomplete initialization responses.
42pub fn initialize_new(binary: &Path, root: &Path) -> Result<(), Error> {
43    initialized(binary, root, "initialize")
44}
45
46/// Populate only the caller's exclusively reserved empty `.git` directory.
47///
48/// # Errors
49/// Rejects nonempty metadata and returns component/initialization failures without fallback.
50pub fn initialize_reserved(binary: &Path, git: &Path) -> Result<(), Error> {
51    initialized(binary, git, "initialize_reserved")
52}
53
54/// Require an affirmative complete response before accepting Git initialization as successful.
55fn initialized(binary: &Path, root: &Path, operation: &str) -> Result<(), Error> {
56    let data = query(Component::Vcs, binary, operation, root, &[])?;
57    if data.get("initialized").and_then(serde_json::Value::as_bool) != Some(true) {
58        return Err(Error::InvalidResponse);
59    }
60    Ok(())
61}