use std::path::Path;
use crate::harness::types::HarnessConfig;
pub fn load_harness_config(project_root: &str) -> Result<HarnessConfig, String> {
let config_path = Path::new(project_root).join(".7").join("harnesses.toml");
let raw = std::fs::read_to_string(&config_path)
.map_err(|_| format!("Harness config not found: {}", config_path.display()))?;
let config: HarnessConfig =
toml::from_str(&raw).map_err(|e| format!("Invalid harness config: {}", e))?;
for (name, entry) in &config.harness {
if entry.args_mapping != "flags" {
return Err(format!(
"Harness \"{}\" has invalid args_mapping \"{}\", must be \"flags\"",
name, entry.args_mapping
));
}
if !matches!(
entry.output_mode,
None | Some(crate::harness::types::HarnessOutputMode::Text)
| Some(crate::harness::types::HarnessOutputMode::StreamJson)
) {
return Err(format!(
"Harness \"{}\" has invalid output_mode, must be \"text\" or \"stream-json\"",
name
));
}
}
Ok(config)
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_load_valid_config() {
let dir = TempDir::new().unwrap();
let dot7 = dir.path().join(".7");
fs::create_dir_all(&dot7).unwrap();
fs::write(
dot7.join("harnesses.toml"),
r#"
[harness.echo-test]
command = "echo"
prompt_slot = "--prompt"
args_mapping = "flags"
output_mode = "stream-json"
"#,
)
.unwrap();
let config = load_harness_config(dir.path().to_str().unwrap()).unwrap();
assert!(config.harness.contains_key("echo-test"));
assert_eq!(config.harness["echo-test"].command, "echo");
assert_eq!(
config.harness["echo-test"].output_mode,
Some(crate::harness::types::HarnessOutputMode::StreamJson)
);
}
#[test]
fn test_load_missing_config() {
let result = load_harness_config("/nonexistent/path");
assert!(result.is_err());
}
#[test]
fn test_invalid_args_mapping() {
let dir = TempDir::new().unwrap();
let dot7 = dir.path().join(".7");
fs::create_dir_all(&dot7).unwrap();
fs::write(
dot7.join("harnesses.toml"),
r#"
[harness.bad]
command = "echo"
prompt_slot = "--prompt"
args_mapping = "positional"
"#,
)
.unwrap();
let result = load_harness_config(dir.path().to_str().unwrap());
assert!(result.is_err());
assert!(result.unwrap_err().contains("args_mapping"));
}
#[test]
fn test_invalid_output_mode() {
let dir = TempDir::new().unwrap();
let dot7 = dir.path().join(".7");
fs::create_dir_all(&dot7).unwrap();
fs::write(
dot7.join("harnesses.toml"),
r#"
[harness.bad]
command = "echo"
prompt_slot = "--prompt"
args_mapping = "flags"
output_mode = "jsonish"
"#,
)
.unwrap();
let result = load_harness_config(dir.path().to_str().unwrap());
assert!(result.is_err());
assert!(result.unwrap_err().contains("Invalid harness config"));
}
}