Skip to content

Commit e34499c

Browse files
committed
feat: enhance commitmsg CLI with improved examples flag handling
- Updated `--examples` flag to accept a custom number of examples (1-20). - Added support for positional arguments to specify examples count. - Improved validation and error handling for `--examples` flag input. - Enhanced README documentation to reflect new `--examples` functionality. - Refactored code to ensure proper cleanup of HTTP response bodies. This update provides greater flexibility for users to customize the number of example commit messages used in context, improving usability and clarity.
1 parent 9f0465a commit e34499c

3 files changed

Lines changed: 53 additions & 13 deletions

File tree

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
Based on [gh-standup](https://github.com/sgoedecke/gh-standup) by Sean Goedecke.
44

5-
A GitHub CLI extension that generates AI-powered commit messages using staged git changes from current repository. It uses free [GitHub Models](https://docs.github.com/en/github-models) for inference, so you don't need to do any token setup - your existing GitHub CLI token will do fine!
5+
A GitHub CLI extension that generates AI-powered [conventional commit](https://www.conventionalcommits.org/en/v1.0.0/#summary) messages using staged git changes from current repository. It uses free [GitHub Models](https://docs.github.com/en/github-models) for inference, so you don't need to do any token setup - your existing GitHub CLI token will do fine!
6+
7+
If you find this utility useful, check my another tool – [gh-repomon](https://github.com/hazadus/gh-repomon).
68

79
## Installation
810

@@ -49,9 +51,12 @@ You can use and combine different options:
4951
# Use different language
5052
gh commitmsg --language russian
5153

52-
# Use previous 3 commit messages as an example for LLM
54+
# Use previous commit messages as examples for LLM (default: 3, max: 20)
5355
gh commitmsg --examples
5456

57+
# Or specify custom number of examples
58+
gh commitmsg --examples 5
59+
5560
# Use a different AI model
5661
gh commitmsg --model xai/grok-3-mini
5762
```

cmd/commitmsg/main.go

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,55 @@ package main
44
import (
55
"fmt"
66
"os"
7+
"strconv"
78

89
"github.com/hazadus/gh-commitmsg/internal/git"
910
"github.com/hazadus/gh-commitmsg/internal/llm"
1011
"github.com/spf13/cobra"
1112
)
1213

13-
const extensionName = "commitmsg"
14+
const (
15+
extensionName = "commitmsg"
16+
maxExamples = 20
17+
)
1418

1519
var (
1620
flagLanguage string
17-
flagExamples bool
18-
flagModel string
21+
flagExamples string
22+
flagModel string
1923
)
2024
var rootCmd = &cobra.Command{
2125
Use: extensionName,
2226
Short: "Generate AI-powered commit messages",
2327
Long: "A GitHub CLI extension that generates commit messages using GitHub Models and git repo data",
2428
RunE: runCommitMsg,
29+
Args: handleArgs,
2530
}
2631

2732
func init() {
2833
rootCmd.Flags().StringVarP(&flagLanguage, "language", "l", "english", "Language to generate commit message in")
29-
rootCmd.Flags().BoolVarP(&flagExamples, "examples", "e", false, "Add examples of commit messages to context")
34+
rootCmd.Flags().StringVarP(&flagExamples, "examples", "e", "", "Add N examples of commit messages to context (default 3 if flag is set without value, max 20)")
35+
rootCmd.Flags().Lookup("examples").NoOptDefVal = "3"
3036
rootCmd.Flags().StringVarP(&flagModel, "model", "m", "openai/gpt-4o", "GitHub Models model to use")
3137
}
3238

39+
// handleArgs processes positional arguments to support --examples N syntax
40+
func handleArgs(cmd *cobra.Command, args []string) error {
41+
// If --examples was set to its NoOptDefVal and there's a positional arg, use it
42+
if flagExamples == "3" && len(args) == 1 {
43+
// Check if examples flag was actually set
44+
if cmd.Flags().Changed("examples") {
45+
flagExamples = args[0]
46+
return nil
47+
}
48+
}
49+
// No positional arguments allowed normally
50+
if len(args) > 0 {
51+
return fmt.Errorf("unexpected argument: %s", args[0])
52+
}
53+
return nil
54+
}
55+
3356
func main() {
3457
if err := rootCmd.Execute(); err != nil {
3558
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
@@ -42,20 +65,32 @@ func runCommitMsg(_ *cobra.Command, _ []string) error {
4265
if err != nil {
4366
return fmt.Errorf("failed to get staged changes: %w", err)
4467
}
45-
68+
4669
if stagedChanges == "" {
4770
fmt.Println("No staged changes in the repository.")
4871
return nil
4972
}
5073

74+
// Parse and validate examples count
75+
examplesCount := 0
76+
if flagExamples != "" {
77+
examplesCount, err = strconv.Atoi(flagExamples)
78+
if err != nil {
79+
return fmt.Errorf("invalid examples count: %s", flagExamples)
80+
}
81+
if examplesCount < 1 || examplesCount > maxExamples {
82+
return fmt.Errorf("examples count must be between 1 and %d", maxExamples)
83+
}
84+
}
85+
5186
// Add examples of previous commit messages to context if the flag is set
5287
latestCommitMessages := ""
53-
if flagExamples {
54-
latestCommitMessages, err = git.GetCommitMessages(3)
88+
if examplesCount > 0 {
89+
latestCommitMessages, err = git.GetCommitMessages(examplesCount)
5590
if err != nil {
5691
return fmt.Errorf("failed to get latest commit messages: %w", err)
5792
}
58-
fmt.Println(" Adding examples of previous commit messages to context")
93+
fmt.Printf(" Adding %d example(s) of previous commit messages to context\n", examplesCount)
5994
}
6095

6196
llmClient, err := llm.NewClient()

internal/llm/client.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ func (c *Client) callGitHubModels(request Request) (*Response, error) {
179179
if err != nil {
180180
return nil, fmt.Errorf("failed to make request: %w", err)
181181
}
182-
defer resp.Body.Close()
182+
defer func() { _ = resp.Body.Close() }()
183183

184184
body, err := io.ReadAll(resp.Body)
185185
if err != nil {
@@ -203,6 +203,6 @@ func createExamplesString(examples string) string {
203203
if examples == "" {
204204
return ""
205205
}
206-
206+
207207
return fmt.Sprintf("Here are some examples of good commit messages used previously in project:\n%s", examples)
208-
}
208+
}

0 commit comments

Comments
 (0)