pub mod bootstrap;
mod cache;
mod core;
mod heartbeats;
mod locks;
mod migration;
mod trust;
#[cfg(test)]
mod tests;
use std::path::Path;
use std::sync::Once;
pub(crate) const HUB_CACHE_DIR: &str = ".hub-cache";
pub(crate) const HUB_BRANCH: &str = "crosslink/hub";
const MAX_DIVERGENCE: usize = 10;
const OLD_CACHE_DIR: &str = ".locks-cache";
const OLD_BRANCH: &str = "crosslink/locks";
pub use crate::signing::SignatureVerification;
pub use self::core::SyncManager;
pub use self::locks::LockMode;
pub fn read_tracker_remote(crosslink_dir: &Path) -> String {
static WARNED: Once = Once::new();
let config_path = crosslink_dir.join("hook-config.json");
let configured = std::fs::read_to_string(&config_path)
.ok()
.and_then(|content| serde_json::from_str::<serde_json::Value>(&content).ok())
.and_then(|v| {
v.get("tracker_remote")
.and_then(|r| r.as_str().map(std::string::ToString::to_string))
});
if let Some(remote) = configured {
return remote;
}
WARNED.call_once(|| {
tracing::warn!(
"no tracker_remote configured in {}, defaulting to \"origin\"",
config_path.display()
);
});
"origin".to_string()
}
#[allow(dead_code)]
#[must_use]
pub fn validate_remote_exists(repo_root: &Path, remote: &str) -> bool {
std::process::Command::new("git")
.current_dir(repo_root)
.args(["remote", "get-url", remote])
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status()
.is_ok_and(|s| s.success())
}