use std::path::{Path, PathBuf};
use anyhow::{Context, Result};
use tracing_subscriber::EnvFilter;
use crate::server::env;
use crate::server::manifest::{Manifest, ManifestError};
use crate::server::watch;
pub fn init_tracing() {
let _ = tracing_subscriber::fmt()
.with_env_filter(
EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")),
)
.with_writer(std::io::stderr)
.with_ansi(false)
.try_init();
}
pub fn load_env_for_mode(manifest: Option<&Manifest>, start_dir: &Path) -> Result<Option<PathBuf>> {
if let Some(m) = manifest {
if let Some(rel) = m.env_file.as_ref() {
let base = m
.yaml_path
.parent()
.map(|p| p.to_path_buf())
.unwrap_or_else(|| PathBuf::from("."));
let resolved = base.join(rel);
env::load_env_explicit(&resolved).map_err(anyhow::Error::msg)?;
return Ok(Some(resolved));
}
}
Ok(env::load_env_walk(start_dir))
}
pub fn resolve_source_roots(manifest: &Manifest) -> Result<Vec<String>, ManifestError> {
let base = manifest
.yaml_path
.parent()
.map(|p| p.to_path_buf())
.unwrap_or_else(|| PathBuf::from("."));
let mut resolved: Vec<String> = Vec::new();
for raw in &manifest.source_roots {
let candidate = base.join(raw);
let canon = candidate.canonicalize().map_err(|_| {
ManifestError::at(
&manifest.yaml_path,
format!(
"source root {raw:?} resolves to {:?} which is not an existing directory",
candidate.display()
),
)
})?;
if !canon.is_dir() {
return Err(ManifestError::at(
&manifest.yaml_path,
format!(
"source root {raw:?} resolves to {:?} which is not a directory",
canon.display()
),
));
}
resolved.push(canon.to_string_lossy().into_owned());
}
Ok(resolved)
}
pub fn maybe_watch(
dir: Option<&Path>,
on_change: Option<watch::ChangeHandler>,
) -> Result<Option<watch::WatchHandle>> {
let Some(d) = dir else { return Ok(None) };
let handle = watch::watch(d, on_change, None).context("failed to start file watcher")?;
Ok(Some(handle))
}