@@ -11,9 +11,11 @@ import (
1111 "github.com/dfanso/commit-msg/internal/gemini"
1212 "github.com/dfanso/commit-msg/internal/git"
1313 "github.com/dfanso/commit-msg/internal/grok"
14+ "github.com/dfanso/commit-msg/internal/ollama"
1415 "github.com/dfanso/commit-msg/internal/stats"
1516 "github.com/dfanso/commit-msg/pkg/types"
1617 "github.com/pterm/pterm"
18+ "github.com/joho/godotenv"
1719)
1820
1921// main is the entry point of the commit message generator
@@ -43,107 +45,120 @@ func main() {
4345 if apiKey == "" {
4446 log .Fatalf ("CLAUDE_API_KEY is not set" )
4547 }
48+ case "ollama" :
49+ // No API key needed for an llm running locally on ollama
50+ apiKey = ""
4651 default :
4752 log .Fatalf ("Invalid COMMIT_LLM value: %s" , commitLLM )
4853 }
4954
50- // Get current directory
51- currentDir , err := os .Getwd ()
52- if err != nil {
53- log .Fatalf ("Failed to get current directory: %v" , err )
55+ // Get current directory
56+ currentDir , err := os .Getwd ()
57+ if err != nil {
58+ log .Fatalf ("Failed to get current directory: %v" , err )
59+ }
60+
61+ // Check if current directory is a git repository
62+ if ! git .IsRepository (currentDir ) {
63+ log .Fatalf ("Current directory is not a Git repository: %s" , currentDir )
64+ }
65+
66+ // Create a minimal config for the API
67+ config := & types.Config {
68+ GrokAPI : "https://api.x.ai/v1/chat/completions" ,
69+ }
70+
71+ // Create a repo config for the current directory
72+ repoConfig := types.RepoConfig {
73+ Path : currentDir ,
74+ }
75+
76+ // Get file statistics before fetching changes
77+ fileStats , err := stats .GetFileStatistics (& repoConfig )
78+ if err != nil {
79+ log .Fatalf ("Failed to get file statistics: %v" , err )
80+ }
81+
82+ // Display header
83+ pterm .DefaultHeader .WithFullWidth ().
84+ WithBackgroundStyle (pterm .NewStyle (pterm .BgDarkGray )).
85+ WithTextStyle (pterm .NewStyle (pterm .FgLightWhite )).
86+ Println ("🚀 Commit Message Generator" )
87+
88+ pterm .Println ()
89+
90+ // Display file statistics with icons
91+ display .ShowFileStatistics (fileStats )
92+
93+ if fileStats .TotalFiles == 0 {
94+ pterm .Warning .Println ("No changes detected in the Git repository." )
95+ return
96+ }
97+
98+ // Get the changes
99+ changes , err := git .GetChanges (& repoConfig )
100+ if err != nil {
101+ log .Fatalf ("Failed to get Git changes: %v" , err )
102+ }
103+
104+ if len (changes ) == 0 {
105+ pterm .Warning .Println ("No changes detected in the Git repository." )
106+ return
107+ }
108+
109+ pterm .Println ()
110+
111+ // Show generating spinner
112+ spinnerGenerating , err := pterm .DefaultSpinner .
113+ WithSequence ("⠋" , "⠙" , "⠹" , "⠸" , "⠼" , "⠴" , "⠦" , "⠧" , "⠇" , "⠏" ).
114+ Start ("🤖 Generating commit message..." )
115+ if err != nil {
116+ log .Fatalf ("Failed to start spinner: %v" , err )
117+ }
118+
119+ var commitMsg string
120+ if os .Getenv ("COMMIT_LLM" ) == "gemini" {
121+ commitMsg , err = gemini .GenerateCommitMessage (config , changes , apiKey )
122+ } else if os .Getenv ("COMMIT_LLM" ) == "chatgpt" {
123+ commitMsg , err = chatgpt .GenerateCommitMessage (config , changes , apiKey )
124+ } else if os .Getenv ("COMMIT_LLM" ) == "claude" {
125+ commitMsg , err = claude .GenerateCommitMessage (config , changes , apiKey )
126+ } else if os .Getenv ("COMMIT_LLM" ) == "ollama" {
127+ url := os .Getenv ("OLLAMA_URL" )
128+ if url == "" {
129+ url = "http://localhost:11434/api/generate"
54130 }
55-
56- // Check if current directory is a git repository
57- if ! git .IsRepository (currentDir ) {
58- log .Fatalf ("Current directory is not a Git repository: %s" , currentDir )
59- }
60-
61- // Create a minimal config for the API
62- config := & types.Config {
63- GrokAPI : "https://api.x.ai/v1/chat/completions" ,
64- }
65-
66- // Create a repo config for the current directory
67- repoConfig := types.RepoConfig {
68- Path : currentDir ,
69- }
70-
71- // Get file statistics before fetching changes
72- fileStats , err := stats .GetFileStatistics (& repoConfig )
73- if err != nil {
74- log .Fatalf ("Failed to get file statistics: %v" , err )
131+ model := os .Getenv ("OLLAMA_MODEL" )
132+ if model == "" {
133+ model = "llama3:latest"
75134 }
135+ commitMsg , err = ollama .GenerateCommitMessage (config , changes , url , model )
136+ } else {
137+ commitMsg , err = grok .GenerateCommitMessage (config , changes , apiKey )
138+ }
76139
77- // Display header
78- pterm .DefaultHeader .WithFullWidth ().
79- WithBackgroundStyle (pterm .NewStyle (pterm .BgDarkGray )).
80- WithTextStyle (pterm .NewStyle (pterm .FgLightWhite )).
81- Println ("🚀 Commit Message Generator" )
82-
83- pterm .Println ()
84-
85- // Display file statistics with icons
86- display .ShowFileStatistics (fileStats )
140+ if err != nil {
141+ spinnerGenerating .Fail ("Failed to generate commit message" )
142+ log .Fatalf ("Error: %v" , err )
143+ }
87144
88- if fileStats .TotalFiles == 0 {
89- pterm .Warning .Println ("No changes detected in the Git repository." )
90- return
91- }
145+ spinnerGenerating .Success ("✅ Commit message generated successfully!" )
92146
93- // Get the changes
94- changes , err := git .GetChanges (& repoConfig )
95- if err != nil {
96- log .Fatalf ("Failed to get Git changes: %v" , err )
97- }
147+ pterm .Println ()
98148
99- if len (changes ) == 0 {
100- pterm .Warning .Println ("No changes detected in the Git repository." )
101- return
102- }
149+ // Display the commit message in a styled panel
150+ display .ShowCommitMessage (commitMsg )
103151
104- pterm .Println ()
105-
106- // Show generating spinner
107- spinnerGenerating , err := pterm .DefaultSpinner .
108- WithSequence ("⠋" , "⠙" , "⠹" , "⠸" , "⠼" , "⠴" , "⠦" , "⠧" , "⠇" , "⠏" ).
109- Start ("🤖 Generating commit message..." )
110- if err != nil {
111- log .Fatalf ("Failed to start spinner: %v" , err )
112- }
113-
114- var commitMsg string
115- if os .Getenv ("COMMIT_LLM" ) == "gemini" {
116- commitMsg , err = gemini .GenerateCommitMessage (config , changes , apiKey )
117- } else if os .Getenv ("COMMIT_LLM" ) == "chatgpt" {
118- commitMsg , err = chatgpt .GenerateCommitMessage (config , changes , apiKey )
119- } else if os .Getenv ("COMMIT_LLM" ) == "claude" {
120- commitMsg , err = claude .GenerateCommitMessage (config , changes , apiKey )
121- } else {
122- commitMsg , err = grok .GenerateCommitMessage (config , changes , apiKey )
123- }
124-
125- if err != nil {
126- spinnerGenerating .Fail ("Failed to generate commit message" )
127- log .Fatalf ("Error: %v" , err )
128- }
129-
130- spinnerGenerating .Success ("✅ Commit message generated successfully!" )
131-
132- pterm .Println ()
133-
134- // Display the commit message in a styled panel
135- display .ShowCommitMessage (commitMsg )
136-
137- // Copy to clipboard
138- err = clipboard .WriteAll (commitMsg )
139- if err != nil {
140- pterm .Warning .Printf ("⚠️ Could not copy to clipboard: %v\n " , err )
141- } else {
142- pterm .Success .Println ("📋 Commit message copied to clipboard!" )
143- }
152+ // Copy to clipboard
153+ err = clipboard .WriteAll (commitMsg )
154+ if err != nil {
155+ pterm .Warning .Printf ("⚠️ Could not copy to clipboard: %v\n " , err )
156+ } else {
157+ pterm .Success .Println ("📋 Commit message copied to clipboard!" )
158+ }
144159
145- pterm .Println ()
160+ pterm .Println ()
146161
147- // Display changes preview
148- display .ShowChangesPreview (fileStats )
162+ // Display changes preview
163+ display .ShowChangesPreview (fileStats )
149164}
0 commit comments