Skip to content

Commit

Permalink
✨ feat: Improve code readability and error handling
Browse files Browse the repository at this point in the history
- Import the "errors" package to support error handling.
- Add logic to handle the context.Canceled error gracefully in the TUI program.
- Remove unnecessary comments and obsolete code fragments for better clarity.
- Adjust the regular expression pattern in BuildRegexPatternWithEmoji for improved formatting.
- Update the BuildPrompt function to ignore non-informative changes in commit message construction.
- Add comments to document functions in the committypes package for better maintainability.
  • Loading branch information
Renato Guilhermini committed Feb 2, 2025
1 parent 1de5983 commit fb21fdb
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 11 deletions.
13 changes: 6 additions & 7 deletions cmd/ai-commit/ai-commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"

"errors"

"github.com/renatogalera/ai-commit/pkg/committypes"
"github.com/renatogalera/ai-commit/pkg/git"
"github.com/renatogalera/ai-commit/pkg/openai"
Expand Down Expand Up @@ -70,8 +72,6 @@ func main() {
}
// After successful interactive splitting, we can optionally do semantic release
if *semanticReleaseFlag {
// In a real scenario, you might gather final messages or read the last commit message
// For demonstration, we'll just look at the HEAD commit message
headMsg, _ := git.GetHeadCommitMessage()
cfg := Config{
APIKey: apiKey,
Expand Down Expand Up @@ -153,6 +153,10 @@ func main() {
model := ui.NewUIModel(commitMsg, cfg.Prompt, cfg.APIKey, cfg.CommitType, cfg.Template)
p := ui.NewProgram(model)
if err := p.Start(); err != nil {
// If the error is due to a normal cancellation, do not treat it as a failure.
if errors.Is(err, context.Canceled) {
os.Exit(0)
}
log.Error().Err(err).Msg("Error running TUI program")
os.Exit(1)
}
Expand Down Expand Up @@ -181,7 +185,6 @@ func generateCommitMessage(ctx context.Context, cfg Config) (string, error) {
return msg, nil
}

// doSemanticRelease triggers the version suggestion logic and optionally tags/releases
func doSemanticRelease(ctx context.Context, cfg Config, commitMsg string) error {
log.Info().Msg("Starting semantic release process...")
currentVersion, err := versioner.GetCurrentVersionTag()
Expand Down Expand Up @@ -212,22 +215,18 @@ func doSemanticRelease(ctx context.Context, cfg Config, commitMsg string) error
return nil
}

// runInteractiveSplit is the main entry point for chunk-based splitting
func runInteractiveSplit(apiKey string) error {
// We'll parse the staged diff into chunks, then run a TUI to let the user pick splits
diff, err := git.GetGitDiff()
if err != nil {
return err
}

// Filter out lock files
diff = git.FilterLockFiles(diff, []string{"go.mod", "go.sum"})
if strings.TrimSpace(diff) == "" {
fmt.Println("No changes to commit (after filtering lock files). Did you stage your changes?")
return nil
}

// We'll parse the diff into chunks
chunks, err := git.ParseDiffToChunks(diff)
if err != nil {
return fmt.Errorf("failed to parse diff: %w", err)
Expand Down
7 changes: 5 additions & 2 deletions pkg/committypes/committypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var validTypes = []string{
"feat", "fix", "docs", "style", "refactor", "test", "chore", "perf", "build", "ci",
}

// IsValidCommitType checks if the provided commit type is in the known list.
func IsValidCommitType(t string) bool {
for _, vt := range validTypes {
if t == vt {
Expand All @@ -18,16 +19,18 @@ func IsValidCommitType(t string) bool {
return false
}

// AllTypes returns the list of valid conventional commit types.
func AllTypes() []string {
return validTypes
}

// TypesRegexPattern joins all valid types for use in a regex pattern.
func TypesRegexPattern() string {
return strings.Join(validTypes, "|")
}

// BuildRegexPatternWithEmoji builds a regex pattern that matches conventional commit messages with emoji.
func BuildRegexPatternWithEmoji() *regexp.Regexp {
pattern := `^((\p{So}|\p{Sk}|:\w+:)\s+)?(` + TypesRegexPattern() + `):`
pattern := `^((\p{So}|\p{Sk}|:\w+:)\s*)?(` + TypesRegexPattern() + `):`
return regexp.MustCompile(pattern)
}

4 changes: 2 additions & 2 deletions pkg/openai/openai.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func BuildPrompt(diff, language, commitType string) string {
sb.WriteString("The commit message must include a short subject line starting with the commit type (e.g., 'feat: Add new feature'), followed by a blank line, and then a detailed body. ")
sb.WriteString("For the body, list each change as a separate bullet point, starting with a hyphen ('-'). ")
sb.WriteString("Write using the present tense and ensure clarity. Output only the commit message with no additional text. ")
sb.WriteString("Ignore changes to lock files (e.g., go.mod, go.sum). ")
sb.WriteString("Ignore changes such as line breaks, blank lines, and information that does not add value to the commit message. ")
if commitType != "" {
sb.WriteString(fmt.Sprintf("Use the commit type '%s'. ", commitType))
}
Expand Down Expand Up @@ -70,7 +70,7 @@ func SanitizeOpenAIResponse(msg, commitType string) string {
msg = strings.TrimSpace(msg)

if commitType != "" {
pattern := regexp.MustCompile(`^(?:(\p{Emoji_Presentation}|\p{So}|\p{Sk}|:\w+:)\s*)?(` + committypes.TypesRegexPattern() + `):\s*|(` + committypes.TypesRegexPattern() + `):\s*`)
pattern := regexp.MustCompile(`^(?:(\p{So}|\p{Sk}|:\w+:)\s*)?(` + committypes.TypesRegexPattern() + `):\s*|(` + committypes.TypesRegexPattern() + `):\s*`)
lines := strings.SplitN(msg, "\n", 2)
if len(lines) > 0 {
lines[0] = pattern.ReplaceAllString(lines[0], "")
Expand Down

0 comments on commit fb21fdb

Please sign in to comment.