use anyhow::Result;
use commitor::{diff, Commitor, Config};
use std::env;
#[tokio::main]
async fn main() -> Result<()> {
println!("🚀 Commitor Basic Usage Examples");
println!("=================================");
println!("\n1. Basic OpenAI Usage");
println!("---------------------");
basic_openai_example().await?;
println!("\n2. Basic Ollama Usage");
println!("---------------------");
basic_ollama_example().await?;
println!("\n3. Custom OpenAI Configuration");
println!("------------------------------");
custom_openai_config_example().await?;
println!("\n4. Custom Ollama Configuration");
println!("------------------------------");
custom_ollama_config_example().await?;
println!("\n5. Error Handling Example");
println!("-------------------------");
error_handling_example().await?;
println!("\n✅ All examples completed!");
Ok(())
}
async fn basic_openai_example() -> Result<()> {
if env::var("OPENAI_API_KEY").is_err() {
println!("⚠️ OPENAI_API_KEY not set, skipping OpenAI examples");
println!(" Set your API key: export OPENAI_API_KEY=\"your-key-here\"");
return Ok(());
}
if !diff::has_staged_changes()? {
println!("⚠️ No staged changes found for OpenAI example");
println!(" Stage some changes first: git add <files>");
return Ok(());
}
let config = Config::new()?;
let commitor = Commitor::new(config)?;
let diff = commitor.get_staged_diff()?;
println!("📝 Staged diff found ({} characters)", diff.len());
println!("🤖 Generating commit messages with OpenAI...");
match commitor.generate_commit_messages(&diff).await {
Ok(messages) => {
println!("✅ Generated {} commit messages:", messages.len());
for (i, message) in messages.iter().enumerate() {
println!(" {}. {}", i + 1, message);
}
}
Err(e) => {
println!("❌ Error generating messages: {}", e);
}
}
Ok(())
}
async fn basic_ollama_example() -> Result<()> {
if !diff::has_staged_changes()? {
println!("⚠️ No staged changes found for Ollama example");
println!(" Stage some changes first: git add <files>");
return Ok(());
}
let config = Config::with_ollama(
"http://localhost:11434".to_string(),
"llama2".to_string(),
3, false, false, );
match Commitor::new(config) {
Ok(commitor) => {
let diff = commitor.get_staged_diff()?;
println!("📝 Staged diff found ({} characters)", diff.len());
println!("🦙 Generating commit messages with Ollama...");
match commitor.generate_commit_messages(&diff).await {
Ok(messages) => {
println!("✅ Generated {} commit messages:", messages.len());
for (i, message) in messages.iter().enumerate() {
println!(" {}. {}", i + 1, message);
}
}
Err(e) => {
println!("❌ Error generating messages: {}", e);
}
}
}
Err(e) => {
println!("⚠️ Ollama not available: {}", e);
println!(" Make sure Ollama is running: ollama serve");
println!(" And you have models installed: ollama pull llama2");
}
}
Ok(())
}
async fn custom_openai_config_example() -> Result<()> {
if env::var("OPENAI_API_KEY").is_err() {
println!("⚠️ OPENAI_API_KEY not set, skipping custom OpenAI example");
return Ok(());
}
if !diff::has_staged_changes()? {
println!("⚠️ No staged changes found for custom OpenAI example");
return Ok(());
}
let api_key = env::var("OPENAI_API_KEY")?;
let config = Config::with_openai(
api_key,
"gpt-3.5-turbo".to_string(), 5, false, true, );
let commitor = Commitor::new(config)?;
let diff = commitor.get_staged_diff()?;
println!("📝 Staged diff found ({} characters)", diff.len());
println!("📄 Diff content preview:");
println!("{}", diff.chars().take(200).collect::<String>());
if diff.len() > 200 {
println!("... (truncated)");
}
println!("🤖 Generating 5 commit messages with GPT-3.5-turbo...");
match commitor.generate_commit_messages(&diff).await {
Ok(messages) => {
println!("✅ Generated {} commit messages:", messages.len());
for (i, message) in messages.iter().enumerate() {
println!(" {}. {}", i + 1, message);
}
}
Err(e) => {
println!("❌ Error generating messages: {}", e);
}
}
Ok(())
}
async fn custom_ollama_config_example() -> Result<()> {
if !diff::has_staged_changes()? {
println!("⚠️ No staged changes found for custom Ollama example");
return Ok(());
}
let config = Config::with_ollama_timeout(
"http://localhost:11434".to_string(),
"codellama".to_string(),
std::time::Duration::from_secs(60), 3, false, true, );
match Commitor::new(config) {
Ok(commitor) => {
let diff = commitor.get_staged_diff()?;
println!("📝 Staged diff found ({} characters)", diff.len());
println!("📄 Diff content preview:");
println!("{}", diff.chars().take(200).collect::<String>());
if diff.len() > 200 {
println!("... (truncated)");
}
println!("🦙 Generating commit messages with CodeLlama (60s timeout)...");
match commitor.generate_commit_messages(&diff).await {
Ok(messages) => {
println!("✅ Generated {} commit messages:", messages.len());
for (i, message) in messages.iter().enumerate() {
println!(" {}. {}", i + 1, message);
}
}
Err(e) => {
println!("❌ Error generating messages: {}", e);
}
}
}
Err(e) => {
println!("⚠️ Ollama not available: {}", e);
println!(" Make sure Ollama is running: ollama serve");
println!(" And you have CodeLlama installed: ollama pull codellama");
}
}
Ok(())
}
async fn error_handling_example() -> Result<()> {
println!("📚 Demonstrating error handling patterns...");
if env::var("OPENAI_API_KEY").is_ok() {
let config = Config::with_openai(
"invalid-api-key".to_string(),
"gpt-4".to_string(),
1,
false,
false,
);
match Commitor::new(config) {
Ok(commitor) => {
let sample_diff = r#"
diff --git a/README.md b/README.md
index 1234567..abcdefg 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
# My Project
This is a sample project.
+Added a new line for testing.
"#;
match commitor.generate_commit_messages(sample_diff).await {
Ok(_) => println!("🤔 This shouldn't happen with invalid key"),
Err(e) => println!("✅ Correctly caught invalid API key error: {}", e),
}
}
Err(e) => println!("✅ Correctly caught config error: {}", e),
}
}
let config = Config::with_ollama(
"http://localhost:99999".to_string(), "nonexistent-model".to_string(),
1,
false,
false,
);
match Commitor::new(config) {
Ok(_) => println!("🤔 This shouldn't succeed with invalid URL"),
Err(e) => println!("✅ Correctly caught Ollama connection error: {}", e),
}
match diff::get_staged_diff() {
Ok(diff) => {
if diff.is_empty() {
println!("✅ Correctly detected no staged changes");
} else {
println!("📝 Found staged changes ({} chars)", diff.len());
}
}
Err(e) => println!("✅ Correctly caught git error: {}", e),
}
Ok(())
}
#[allow(dead_code)]
async fn diff_scenarios_example() -> Result<()> {
println!("📋 Testing different diff scenarios...");
let sample_scenarios = vec![
("feat: add user authentication", "Added login functionality"),
(
"fix: resolve memory leak",
"Fixed buffer overflow in parser",
),
("docs: update README", "Updated installation instructions"),
(
"refactor: simplify error handling",
"Consolidated error types",
),
];
for (expected_type, description) in sample_scenarios {
println!("🎯 Scenario: {} - {}", expected_type, description);
}
Ok(())
}