From 5039b749263a2a28f50102e3756edf24a9b9a1a0 Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Fri, 28 Aug 2026 18:03:12 -0600 Subject: [PATCH] test: fix Windows crlf issue and pin the template to lf to prevent future regressions --- .gitattributes | 1 + src/config/mod.rs | 32 +++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e05c06b --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +assets/config-template.yaml text eol=lf diff --git a/src/config/mod.rs b/src/config/mod.rs index bc95e9f..bbefe1d 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -857,6 +857,15 @@ fn render_config_template( model: &str, secrets: Option<&serde_json::Value>, clients: &serde_json::Value, +) -> Result { + render_config_template_from(CONFIG_TEMPLATE, model, secrets, clients) +} + +fn render_config_template_from( + template: &str, + model: &str, + secrets: Option<&serde_json::Value>, + clients: &serde_json::Value, ) -> Result { let to_yaml = |value: &serde_json::Value| { serde_yaml::to_string(value).with_context(|| "Failed to create config") @@ -871,7 +880,8 @@ fn render_config_template( }; let clients_block = to_yaml(&json!({ CLIENTS_FIELD: clients }))?; - Ok(CONFIG_TEMPLATE + Ok(template + .replace("\r\n", "\n") .replacen("__MODEL_BLOCK__\n", &model_block, 1) .replacen("__SECRETS_BLOCK__\n", &secrets_block, 1) .replacen("__CLIENTS_BLOCK__\n", &clients_block, 1)) @@ -1182,6 +1192,26 @@ clients: assert_eq!(cfg.clients.len(), 1); } + #[test] + fn config_template_renders_with_crlf_line_endings() { + let crlf_template = CONFIG_TEMPLATE.replace('\n', "\r\n"); + let secrets = json!({ "vault_password_file": "/home/user/.coyote_password" }); + let clients = json!([{ "type": "openai", "api_key": "sk-test" }]); + + let rendered = + render_config_template_from(&crlf_template, "openai:gpt-4o", Some(&secrets), &clients) + .unwrap(); + + assert!(!rendered.contains("__MODEL_BLOCK__")); + assert!(!rendered.contains("__SECRETS_BLOCK__")); + assert!(!rendered.contains("__CLIENTS_BLOCK__")); + assert!(!rendered.contains('\r')); + + let cfg = Config::load_from_str(&rendered).unwrap(); + assert_eq!(cfg.model_id, "openai:gpt-4o"); + assert_eq!(cfg.clients.len(), 1); + } + #[test] fn config_enabled_macros_empty_string_is_some_empty() { let cfg: Config = serde_yaml::from_str("enabled_macros: \"\"").unwrap();