Skip to content

Commit c655df2

Browse files
committed
feat: check ollama during setup
1 parent 70b9628 commit c655df2

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

crates/cli/src/setup.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::fs;
2+
use std::io::ErrorKind;
23
use std::path::PathBuf;
4+
use std::process::Command;
35

46
use anyhow::{anyhow, Context, Result};
57
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Password, Select};
@@ -78,6 +80,10 @@ pub fn run_setup() -> Result<()> {
7880
.default(default_model.to_string())
7981
.interact_text()?;
8082

83+
if provider_kind == ProviderKind::Ollama {
84+
check_ollama(&model)?;
85+
}
86+
8187
let push = Confirm::with_theme(&theme)
8288
.with_prompt("Push by default after commit?")
8389
.default(true)
@@ -114,6 +120,52 @@ fn ensure_ignore_file(path: &PathBuf) -> Result<()> {
114120
fs::write(path, content).context("failed to write ignore file")
115121
}
116122

123+
fn check_ollama(model: &str) -> Result<()> {
124+
let output = match Command::new("ollama").arg("list").output() {
125+
Ok(output) => output,
126+
Err(err) if err.kind() == ErrorKind::NotFound => {
127+
ui::warn("ollama not found");
128+
ui::info("install ollama from https://ollama.com");
129+
return Ok(());
130+
}
131+
Err(err) => return Err(err.into()),
132+
};
133+
134+
if !output.status.success() {
135+
let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
136+
ui::warn("ollama is installed but not running");
137+
if !stderr.is_empty() {
138+
ui::warn(&format!("ollama list failed: {stderr}"));
139+
}
140+
ui::info("start ollama with: ollama serve");
141+
return Ok(());
142+
}
143+
144+
let stdout = String::from_utf8_lossy(&output.stdout);
145+
let models = parse_ollama_models(&stdout);
146+
if models.is_empty() {
147+
ui::warn("no ollama models installed");
148+
ui::info("pull one with: ollama pull <model>");
149+
return Ok(());
150+
}
151+
152+
if !models.iter().any(|name| name == model) {
153+
ui::warn(&format!("model not found in ollama: {model}"));
154+
ui::info(&format!("pull it with: ollama pull {model}"));
155+
}
156+
157+
Ok(())
158+
}
159+
160+
fn parse_ollama_models(output: &str) -> Vec<String> {
161+
output
162+
.lines()
163+
.filter_map(|line| line.split_whitespace().next())
164+
.filter(|name| *name != "NAME")
165+
.map(|name| name.to_string())
166+
.collect()
167+
}
168+
117169
#[cfg(unix)]
118170
fn set_config_permissions(path: &PathBuf) -> Result<()> {
119171
use std::os::unix::fs::PermissionsExt;

0 commit comments

Comments
 (0)