Skip to content

Commit da48cdb

Browse files
committed
feat: add language support for commit message generation
- Introduced a `--language` flag to specify the language for commit message generation in the CLI. - Updated `cobra` integration to handle the new `--language` flag. - Modified `GenerateCommitMessage` to accept a language parameter and default to the language specified in the prompt configuration. - Updated the prompt configuration to include a `language` field with a default value of "english". - Enhanced template variable replacement to support dynamic language selection. - Added `format` and `lint` tasks to the `Justfile` for code formatting and linting. - Updated `README.md` with usage instructions for the `--language` flag. - Added new dependencies (`cobra`, `pflag`, and others) to `go.mod` and `go.sum`.
1 parent 519bdf9 commit da48cdb

File tree

8 files changed

+67
-14
lines changed

8 files changed

+67
-14
lines changed

Justfile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,10 @@ run:
22
go run cmd/commitmsg/main.go
33

44
build:
5-
go build -o ./bin/commitmsg cmd/commitmsg/main.go
5+
go build -o ./bin/commitmsg cmd/commitmsg/main.go
6+
7+
format:
8+
go fmt ./...
9+
10+
lint:
11+
golangci-lint run ./...

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,10 @@ Tool idea:
44
- get staged changes in the git repository in the current directory
55
- feed the obtained data to the GitHub Models LLM to generate a conventional commit message
66
- display the generated commit message on the screen
7-
- if it works well, we can provide several previous commit messages as examples for the model
7+
- if it works well, we can provide several previous commit messages as examples for the model
8+
9+
## Usage
10+
11+
```bash
12+
commitmsg --language russian
13+
```

cmd/commitmsg/main.go

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,54 @@ import (
77

88
"github.com/hazadus/gh-commitmsg/internal/git"
99
"github.com/hazadus/gh-commitmsg/internal/llm"
10+
"github.com/spf13/cobra"
1011
)
1112

13+
const extensionName = "standup"
14+
15+
var (
16+
flagLanguage string
17+
)
18+
var rootCmd = &cobra.Command{
19+
Use: extensionName,
20+
Short: "Generate AI-powered commit messages",
21+
Long: "A GitHub CLI extension that generates commit messages using GitHub Models and git repo data",
22+
RunE: runCommitMsg,
23+
}
24+
25+
func init() {
26+
rootCmd.Flags().StringVarP(&flagLanguage, "language", "l", "english", "Language to generate commit message in")
27+
}
28+
1229
func main() {
30+
if err := rootCmd.Execute(); err != nil {
31+
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
32+
os.Exit(1)
33+
}
34+
}
35+
36+
func runCommitMsg(_ *cobra.Command, _ []string) error {
1337
stagedChanges, err := git.GetStagedChanges()
1438
if err != nil {
15-
fmt.Printf("Error retrieving staged changes: %v\n", err)
16-
os.Exit(1)
39+
return fmt.Errorf("failed to get staged changes: %w", err)
1740
}
1841

1942
if stagedChanges == "" {
2043
fmt.Println("No staged changes in the repository.")
21-
return
44+
return nil
2245
}
2346

2447
llmClient, err := llm.NewClient()
2548
if err != nil {
26-
fmt.Printf("Error creating LLM client: %v\n", err)
27-
os.Exit(1)
49+
return fmt.Errorf("failed to create LLM client: %w", err)
2850
}
2951

30-
commitMsg, err := llmClient.GenerateCommitMessage(stagedChanges)
52+
commitMsg, err := llmClient.GenerateCommitMessage(stagedChanges, flagLanguage)
3153
if err != nil {
32-
fmt.Printf("Error generating commit message: %v\n", err)
33-
os.Exit(1)
54+
return fmt.Errorf("failed to generate commit message: %w", err)
3455
}
3556

3657
fmt.Println("Generated commit message:")
3758
fmt.Println(commitMsg)
59+
return nil
3860
}
39-

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ go 1.23.4
44

55
require (
66
github.com/cli/go-gh/v2 v2.12.1
7+
github.com/spf13/cobra v1.9.1
78
gopkg.in/yaml.v3 v3.0.1
89
)
910

1011
require (
1112
github.com/cli/safeexec v1.0.0 // indirect
13+
github.com/inconshreveable/mousetrap v1.1.0 // indirect
1214
github.com/kr/pretty v0.3.1 // indirect
15+
github.com/spf13/pflag v1.0.6 // indirect
1316
)

go.sum

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ github.com/cli/go-gh/v2 v2.12.1 h1:SVt1/afj5FRAythyMV3WJKaUfDNsxXTIe7arZbwTWKA=
22
github.com/cli/go-gh/v2 v2.12.1/go.mod h1:+5aXmEOJsH9fc9mBHfincDwnS02j2AIA/DsTH0Bk5uw=
33
github.com/cli/safeexec v1.0.0 h1:0VngyaIyqACHdcMNWfo6+KdUYnqEr2Sg+bSP1pdF+dI=
44
github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
5+
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
56
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
67
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
78
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
10+
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
811
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
912
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
1013
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -14,6 +17,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
1417
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1518
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
1619
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
20+
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
21+
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
22+
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
23+
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
24+
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
1725
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
1826
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
1927
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

internal/git/git.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ func isGitRepository() bool {
2828
cmd := exec.Command("git", "rev-parse", "--is-inside-work-tree")
2929
err := cmd.Run()
3030
return err == nil
31-
}
31+
}

internal/llm/client.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type PromptConfig struct {
2424
Name string `yaml:"name"`
2525
Description string `yaml:"description"`
2626
Model string `yaml:"model"`
27+
Language string `yaml:"language"`
2728
ModelParameters ModelParameters `yaml:"modelParameters"`
2829
Messages []PromptMessage `yaml:"messages"`
2930
}
@@ -87,7 +88,7 @@ func NewClient() (*Client, error) {
8788
}
8889

8990
// GenerateCommitMessage generates a commit message based on the provided changes summary
90-
func (c *Client) GenerateCommitMessage(changesSummary string) (string, error) {
91+
func (c *Client) GenerateCommitMessage(changesSummary string, language string) (string, error) {
9192
fmt.Print(" Loading prompt configuration... ")
9293
promptConfig, err := loadPromptConfig()
9394
if err != nil {
@@ -97,13 +98,18 @@ func (c *Client) GenerateCommitMessage(changesSummary string) (string, error) {
9798
fmt.Println("Done")
9899

99100
selectedModel := promptConfig.Model
101+
selectedLanguage := language
102+
if selectedLanguage == "" {
103+
selectedLanguage = promptConfig.Language
104+
}
100105

101106
// Build messages from the prompt config, replacing template variables
102107
messages := make([]Message, len(promptConfig.Messages))
103108
for i, msg := range promptConfig.Messages {
104109
content := msg.Content
105-
// Replace the {{changes}} template variable
110+
// Replace the template variables
106111
content = strings.ReplaceAll(content, "{{changes}}", changesSummary)
112+
content = strings.ReplaceAll(content, "{{language}}", selectedLanguage)
107113

108114
messages[i] = Message{
109115
Role: msg.Role,

internal/llm/commitmsg.prompt.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: Commit Message Generator
22
description: Generates professional commit messages based on git changes
33
model: openai/gpt-4o
4+
language: english
45
messages:
56
- role: system
67
content: >
@@ -10,6 +11,8 @@ messages:
1011
follows "conventional commits" style. The message should be clear,
1112
informative, and suitable for a professional software development context.
1213
14+
Write in {{language}} language.
15+
1316
Guidelines:
1417
1518
- Keep it professional but conversational

0 commit comments

Comments
 (0)