Skip to content

Commit f29c332

Browse files
read api keys from config file
1 parent 17d5e74 commit f29c332

8 files changed

Lines changed: 436 additions & 63 deletions

File tree

cmd/cli/createMsg.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package cmd
2+
3+
import (
4+
"log"
5+
"os"
6+
7+
"github.com/atotto/clipboard"
8+
"github.com/dfanso/commit-msg/cmd/cli/store"
9+
"github.com/dfanso/commit-msg/internal/chatgpt"
10+
"github.com/dfanso/commit-msg/internal/claude"
11+
"github.com/dfanso/commit-msg/internal/display"
12+
"github.com/dfanso/commit-msg/internal/gemini"
13+
"github.com/dfanso/commit-msg/internal/git"
14+
"github.com/dfanso/commit-msg/internal/grok"
15+
"github.com/dfanso/commit-msg/internal/stats"
16+
"github.com/dfanso/commit-msg/pkg/types"
17+
"github.com/pterm/pterm"
18+
)
19+
20+
21+
func CreateCommitMsg () {
22+
23+
// Validate COMMIT_LLM and required API keys
24+
useLLM,err := store.DefaultLLMKey()
25+
if err != nil {
26+
log.Fatal(err)
27+
}
28+
29+
commitLLM := useLLM.LLM
30+
apiKey := useLLM.APIKey
31+
32+
33+
// Get current directory
34+
currentDir, err := os.Getwd()
35+
if err != nil {
36+
log.Fatalf("Failed to get current directory: %v", err)
37+
}
38+
39+
// Check if current directory is a git repository
40+
if !git.IsRepository(currentDir) {
41+
log.Fatalf("Current directory is not a Git repository: %s", currentDir)
42+
}
43+
44+
// Create a minimal config for the API
45+
config := &types.Config{
46+
GrokAPI: "https://api.x.ai/v1/chat/completions",
47+
}
48+
49+
// Create a repo config for the current directory
50+
repoConfig := types.RepoConfig{
51+
Path: currentDir,
52+
}
53+
54+
// Get file statistics before fetching changes
55+
fileStats, err := stats.GetFileStatistics(&repoConfig)
56+
if err != nil {
57+
log.Fatalf("Failed to get file statistics: %v", err)
58+
}
59+
60+
// Display header
61+
pterm.DefaultHeader.WithFullWidth().
62+
WithBackgroundStyle(pterm.NewStyle(pterm.BgDarkGray)).
63+
WithTextStyle(pterm.NewStyle(pterm.FgLightWhite)).
64+
Println("🚀 Commit Message Generator")
65+
66+
pterm.Println()
67+
68+
// Display file statistics with icons
69+
display.ShowFileStatistics(fileStats)
70+
71+
if fileStats.TotalFiles == 0 {
72+
pterm.Warning.Println("No changes detected in the Git repository.")
73+
return
74+
}
75+
76+
// Get the changes
77+
changes, err := git.GetChanges(&repoConfig)
78+
if err != nil {
79+
log.Fatalf("Failed to get Git changes: %v", err)
80+
}
81+
82+
if len(changes) == 0 {
83+
pterm.Warning.Println("No changes detected in the Git repository.")
84+
return
85+
}
86+
87+
pterm.Println()
88+
89+
// Show generating spinner
90+
spinnerGenerating, err := pterm.DefaultSpinner.
91+
WithSequence("⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏").
92+
Start("🤖 Generating commit message...")
93+
if err != nil {
94+
log.Fatalf("Failed to start spinner: %v", err)
95+
}
96+
97+
var commitMsg string
98+
99+
switch commitLLM {
100+
101+
case "Gemini":
102+
commitMsg, err = gemini.GenerateCommitMessage(config, changes, apiKey)
103+
104+
case "OpenAI":
105+
commitMsg, err = chatgpt.GenerateCommitMessage(config, changes, apiKey)
106+
107+
case "Claude":
108+
commitMsg, err = claude.GenerateCommitMessage(config, changes, apiKey)
109+
110+
default:
111+
commitMsg, err = grok.GenerateCommitMessage(config, changes, apiKey)
112+
}
113+
114+
115+
if err != nil {
116+
spinnerGenerating.Fail("Failed to generate commit message")
117+
log.Fatalf("Error: %v", err)
118+
}
119+
120+
spinnerGenerating.Success("✅ Commit message generated successfully!")
121+
122+
pterm.Println()
123+
124+
// Display the commit message in a styled panel
125+
display.ShowCommitMessage(commitMsg)
126+
127+
// Copy to clipboard
128+
err = clipboard.WriteAll(commitMsg)
129+
if err != nil {
130+
pterm.Warning.Printf("⚠️ Could not copy to clipboard: %v\n", err)
131+
} else {
132+
pterm.Success.Println("📋 Commit message copied to clipboard!")
133+
}
134+
135+
pterm.Println()
136+
137+
// Display changes preview
138+
display.ShowChangesPreview(fileStats)
139+
140+
}

cmd/cli/llmSetup.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/dfanso/commit-msg/cmd/cli/store"
7+
"github.com/manifoldco/promptui"
8+
)
9+
10+
11+
func SetupLLM() error {
12+
13+
providers := []string{"OpenAI", "Claude", "Gemini", "Grok"}
14+
prompt := promptui.Select{
15+
Label: "Select LLM",
16+
Items: providers,
17+
}
18+
19+
_, model, err := prompt.Run()
20+
if err != nil {
21+
return fmt.Errorf("prompt failed")
22+
}
23+
24+
apiKeyPrompt := promptui.Prompt{
25+
Label: "Enter API Key",
26+
27+
}
28+
29+
apiKey, err := apiKeyPrompt.Run()
30+
if err != nil {
31+
return fmt.Errorf("invalid API Key")
32+
}
33+
34+
LLMConfig := store.LLMProvider{
35+
LLM: model,
36+
APIKey: apiKey,
37+
}
38+
39+
40+
41+
err = store.Save(LLMConfig)
42+
if err != nil {
43+
return err
44+
}
45+
46+
fmt.Println("LLM model added")
47+
return nil
48+
}
49+
50+
func UpdateLLM() error {
51+
fmt.Println("Update LLM config")
52+
return nil
53+
}

cmd/root.go renamed to cmd/cli/root.go

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/*
22
Copyright © 2025 NAME HERE <EMAIL ADDRESS>
3-
43
*/
54
package cmd
65

@@ -10,18 +9,11 @@ import (
109
"github.com/spf13/cobra"
1110
)
1211

13-
14-
1512
// rootCmd represents the base command when called without any subcommands
1613
var rootCmd = &cobra.Command{
17-
Use: "commit-msg",
18-
Short: "A brief description of your application",
19-
Long: `A longer description that spans multiple lines and likely contains
20-
examples and usage of using your application. For example:
21-
22-
Cobra is a CLI library for Go that empowers applications.
23-
This application is a tool to generate the needed files
24-
to quickly create a Cobra application.`,
14+
Use: "commit",
15+
Short: "CLI tool to write commit message",
16+
Long: `Write a commit message with AI of your choice`,
2517
// Uncomment the following line if your bare application
2618
// has an action associated with it:
2719
// Run: func(cmd *cobra.Command, args []string) { },
@@ -36,6 +28,36 @@ func Execute() {
3628
}
3729
}
3830

31+
var llmCmd = &cobra.Command{
32+
Use: "llm",
33+
Short: "Manage LLM configuration",
34+
}
35+
36+
var llmSetupCmd = &cobra.Command{
37+
Use: "setup",
38+
Short: "Setup your LLM provider and API key",
39+
RunE: func(cmd *cobra.Command, args []string) error {
40+
return SetupLLM()
41+
},
42+
}
43+
44+
var llmUpdateCmd = &cobra.Command{
45+
Use: "update",
46+
Short: "Update or Delete LLM Model",
47+
RunE: func(cmd *cobra.Command, args []string) error {
48+
return UpdateLLM()
49+
},
50+
}
51+
52+
var creatCommitMsg = &cobra.Command{
53+
Use: ".",
54+
Short: "Create Commit Message",
55+
RunE: func(cmd *cobra.Command, args []string) error {
56+
CreateCommitMsg()
57+
return nil
58+
},
59+
}
60+
3961
func init() {
4062
// Here you will define your flags and configuration settings.
4163
// Cobra supports persistent flags, which, if defined here,
@@ -46,6 +68,9 @@ func init() {
4668
// Cobra also supports local flags, which will only run
4769
// when this action is called directly.
4870
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
71+
rootCmd.AddCommand(llmCmd)
72+
llmCmd.AddCommand(llmSetupCmd)
73+
llmCmd.AddCommand(llmUpdateCmd)
74+
rootCmd.AddCommand(creatCommitMsg)
4975
}
5076

51-

0 commit comments

Comments
 (0)