diff --git a/cmd/commit-msg/main.go b/cmd/commit-msg/main.go index 79c0c38..5ff3083 100644 --- a/cmd/commit-msg/main.go +++ b/cmd/commit-msg/main.go @@ -21,150 +21,150 @@ import ( // main is the entry point of the commit message generator func main() { // Load the .env file - if err := godotenv.Load(); err != nil { - log.Printf("warning: unable to load .env file: %v", err) - } - - // Validate COMMIT_LLM and required API keys - commitLLM := os.Getenv("COMMIT_LLM") - var apiKey string - - switch commitLLM { - case "gemini": - apiKey = os.Getenv("GEMINI_API_KEY") - if apiKey == "" { - log.Fatalf("GEMINI_API_KEY is not set") - } - case "grok": - apiKey = os.Getenv("GROK_API_KEY") - if apiKey == "" { - log.Fatalf("GROK_API_KEY is not set") - } - case "chatgpt": - apiKey = os.Getenv("OPENAI_API_KEY") - if apiKey == "" { - log.Fatalf("OPENAI_API_KEY is not set") - } - case "claude": - apiKey = os.Getenv("CLAUDE_API_KEY") - if apiKey == "" { - log.Fatalf("CLAUDE_API_KEY is not set") - } + // Try to load .env file, but don't fail if it doesn't exist + // System environment variables will be used as fallback + _ = godotenv.Load() + + // Validate COMMIT_LLM and required API keys + commitLLM := os.Getenv("COMMIT_LLM") + var apiKey string + + switch commitLLM { + case "gemini": + apiKey = os.Getenv("GEMINI_API_KEY") + if apiKey == "" { + log.Fatalf("GEMINI_API_KEY is not set") + } + case "grok": + apiKey = os.Getenv("GROK_API_KEY") + if apiKey == "" { + log.Fatalf("GROK_API_KEY is not set") + } + case "chatgpt": + apiKey = os.Getenv("OPENAI_API_KEY") + if apiKey == "" { + log.Fatalf("OPENAI_API_KEY is not set") + } + case "claude": + apiKey = os.Getenv("CLAUDE_API_KEY") + if apiKey == "" { + log.Fatalf("CLAUDE_API_KEY is not set") + } case "ollama": // No API key required to run a local LLM apiKey = "" - default: - log.Fatalf("Invalid COMMIT_LLM value: %s", commitLLM) - } - - // Get current directory - currentDir, err := os.Getwd() - if err != nil { - log.Fatalf("Failed to get current directory: %v", err) - } + default: + log.Fatalf("Invalid COMMIT_LLM value: %s", commitLLM) + } - // Check if current directory is a git repository - if !git.IsRepository(currentDir) { - log.Fatalf("Current directory is not a Git repository: %s", currentDir) - } + // Get current directory + currentDir, err := os.Getwd() + if err != nil { + log.Fatalf("Failed to get current directory: %v", err) + } - // Create a minimal config for the API - config := &types.Config{ - GrokAPI: "https://api.x.ai/v1/chat/completions", - } + // Check if current directory is a git repository + if !git.IsRepository(currentDir) { + log.Fatalf("Current directory is not a Git repository: %s", currentDir) + } - // Create a repo config for the current directory - repoConfig := types.RepoConfig{ - Path: currentDir, - } + // Create a minimal config for the API + config := &types.Config{ + GrokAPI: "https://api.x.ai/v1/chat/completions", + } - // Get file statistics before fetching changes - fileStats, err := stats.GetFileStatistics(&repoConfig) - if err != nil { - log.Fatalf("Failed to get file statistics: %v", err) - } + // Create a repo config for the current directory + repoConfig := types.RepoConfig{ + Path: currentDir, + } - // Display header - pterm.DefaultHeader.WithFullWidth(). - WithBackgroundStyle(pterm.NewStyle(pterm.BgDarkGray)). - WithTextStyle(pterm.NewStyle(pterm.FgLightWhite)). - Println("🚀 Commit Message Generator") + // Get file statistics before fetching changes + fileStats, err := stats.GetFileStatistics(&repoConfig) + if err != nil { + log.Fatalf("Failed to get file statistics: %v", err) + } - pterm.Println() + // Display header + pterm.DefaultHeader.WithFullWidth(). + WithBackgroundStyle(pterm.NewStyle(pterm.BgDarkGray)). + WithTextStyle(pterm.NewStyle(pterm.FgLightWhite)). + Println("🚀 Commit Message Generator") - // Display file statistics with icons - display.ShowFileStatistics(fileStats) + pterm.Println() - if fileStats.TotalFiles == 0 { - pterm.Warning.Println("No changes detected in the Git repository.") - return - } + // Display file statistics with icons + display.ShowFileStatistics(fileStats) - // Get the changes - changes, err := git.GetChanges(&repoConfig) - if err != nil { - log.Fatalf("Failed to get Git changes: %v", err) - } + if fileStats.TotalFiles == 0 { + pterm.Warning.Println("No changes detected in the Git repository.") + return + } - if len(changes) == 0 { - pterm.Warning.Println("No changes detected in the Git repository.") - return - } + // Get the changes + changes, err := git.GetChanges(&repoConfig) + if err != nil { + log.Fatalf("Failed to get Git changes: %v", err) + } - pterm.Println() + if len(changes) == 0 { + pterm.Warning.Println("No changes detected in the Git repository.") + return + } - // Show generating spinner - spinnerGenerating, err := pterm.DefaultSpinner. - WithSequence("⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"). - Start("🤖 Generating commit message...") - if err != nil { - log.Fatalf("Failed to start spinner: %v", err) - } + pterm.Println() - var commitMsg string - switch commitLLM { - case "gemini": - commitMsg, err = gemini.GenerateCommitMessage(config, changes, apiKey) - case "chatgpt": - commitMsg, err = chatgpt.GenerateCommitMessage(config, changes, apiKey) - case "claude": - commitMsg, err = claude.GenerateCommitMessage(config, changes, apiKey) - case "ollama": - url := os.Getenv("OLLAMA_URL") - if url == "" { - url = "http://localhost:11434/api/generate" - } - model := os.Getenv("OLLAMA_MODEL") - if model == "" { - model = "llama3:latest" - } - commitMsg, err = ollama.GenerateCommitMessage(config, changes, url, model) - default: - commitMsg, err = grok.GenerateCommitMessage(config, changes, apiKey) - } + // Show generating spinner + spinnerGenerating, err := pterm.DefaultSpinner. + WithSequence("⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"). + Start("🤖 Generating commit message...") + if err != nil { + log.Fatalf("Failed to start spinner: %v", err) + } - if err != nil { - spinnerGenerating.Fail("Failed to generate commit message") - log.Fatalf("Error: %v", err) + var commitMsg string + switch commitLLM { + case "gemini": + commitMsg, err = gemini.GenerateCommitMessage(config, changes, apiKey) + case "chatgpt": + commitMsg, err = chatgpt.GenerateCommitMessage(config, changes, apiKey) + case "claude": + commitMsg, err = claude.GenerateCommitMessage(config, changes, apiKey) + case "ollama": + url := os.Getenv("OLLAMA_URL") + if url == "" { + url = "http://localhost:11434/api/generate" } + model := os.Getenv("OLLAMA_MODEL") + if model == "" { + model = "llama3:latest" + } + commitMsg, err = ollama.GenerateCommitMessage(config, changes, url, model) + default: + commitMsg, err = grok.GenerateCommitMessage(config, changes, apiKey) + } - spinnerGenerating.Success("✅ Commit message generated successfully!") + if err != nil { + spinnerGenerating.Fail("Failed to generate commit message") + log.Fatalf("Error: %v", err) + } - pterm.Println() + spinnerGenerating.Success("✅ Commit message generated successfully!") - // Display the commit message in a styled panel - display.ShowCommitMessage(commitMsg) + pterm.Println() - // Copy to clipboard - err = clipboard.WriteAll(commitMsg) - if err != nil { - pterm.Warning.Printf("⚠️ Could not copy to clipboard: %v\n", err) - } else { - pterm.Success.Println("📋 Commit message copied to clipboard!") - } + // Display the commit message in a styled panel + display.ShowCommitMessage(commitMsg) + + // Copy to clipboard + err = clipboard.WriteAll(commitMsg) + if err != nil { + pterm.Warning.Printf("⚠️ Could not copy to clipboard: %v\n", err) + } else { + pterm.Success.Println("📋 Commit message copied to clipboard!") + } - pterm.Println() + pterm.Println() - // Display changes preview - display.ShowChangesPreview(fileStats) + // Display changes preview + display.ShowChangesPreview(fileStats) }