use std::path::Path;
use std::sync::Arc;
use anyhow::{Context, Result};
use crate::config::{self, Config, DocumentsCliOverrides};
use crate::git::Repo;
use crate::git_cache::GitCache;
use crate::mcp::BasemindServer;
use crate::store::{LockHolder, Store};
use super::exit::CliExit;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Intent {
Read,
Rescan,
}
const CLI_GIT_CACHE_MEM: usize = 256;
pub fn build_server(root: &Path, view: &str, documents: DocumentsCliOverrides) -> Result<BasemindServer> {
build_server_for(root, view, documents, Intent::Read)
}
pub fn build_server_for(
root: &Path,
view: &str,
documents: DocumentsCliOverrides,
intent: Intent,
) -> Result<BasemindServer> {
let daemon = super::rescan::daemon_is_up();
let store = if daemon {
Store::open_read_only_no_index(root, view).context("open store (blobs only; the daemon holds the index)")?
} else if intent == Intent::Rescan {
Store::open_with_holder(root, view, LockHolder::Rescan).map_err(|err| {
if err.is_lock_contention() {
CliExit::busy(crate::store::LOCK_CONTENTION_HELP)
} else {
anyhow::Error::new(err).context("open store (rescan)")
}
})?
} else {
Store::open_read_only(root, view).context("open store (read-only)")?
};
let basemind_dir = store.basemind_dir.clone();
let cfg = Arc::new(load_config(root, documents)?);
let repo = Repo::discover(root).ok().map(Arc::new);
let git_cache = Arc::new(GitCache::open(&basemind_dir, CLI_GIT_CACHE_MEM, false).context("open git cache")?);
#[cfg(all(feature = "comms", any(unix, windows)))]
if daemon {
return Ok(BasemindServer::new_with_options(
store,
root.to_path_buf(),
cfg,
repo,
git_cache,
crate::mcp::ServerOptions {
background: false,
watch: false,
read_only: true,
daemon_writer: true,
lazy_cache: true,
},
));
}
Ok(BasemindServer::new_oneshot(
store,
root.to_path_buf(),
cfg,
repo,
git_cache,
))
}
fn load_config(root: &Path, documents: DocumentsCliOverrides) -> Result<Config> {
match config::load_with_overrides(root, None, Some(documents)) {
Ok(loaded) => Ok(loaded.config),
Err(config::ConfigError::NotFound(_)) => Ok(config::default_for_root(root)),
Err(e) => Err(anyhow::anyhow!(e)),
}
}