Skip to content

Commit 463aef4

Browse files
committed
feat(cli): añade comando de actualización y muestra uso de tokens de IA
1 parent 04554bd commit 463aef4

20 files changed

Lines changed: 989 additions & 19 deletions

cmd/main.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/Tomas-vilte/MateCommit/internal/cli/command/pull_requests"
1313
"github.com/Tomas-vilte/MateCommit/internal/cli/command/release"
1414
"github.com/Tomas-vilte/MateCommit/internal/cli/command/suggests_commits"
15+
"github.com/Tomas-vilte/MateCommit/internal/cli/command/update"
1516
"github.com/Tomas-vilte/MateCommit/internal/cli/registry"
1617
cfg "github.com/Tomas-vilte/MateCommit/internal/config"
1718
"github.com/Tomas-vilte/MateCommit/internal/i18n"
@@ -21,6 +22,8 @@ import (
2122
"github.com/Tomas-vilte/MateCommit/internal/infrastructure/git"
2223
"github.com/Tomas-vilte/MateCommit/internal/infrastructure/tickets/jira"
2324
"github.com/Tomas-vilte/MateCommit/internal/infrastructure/vcs/github"
25+
"github.com/Tomas-vilte/MateCommit/internal/services"
26+
"github.com/Tomas-vilte/MateCommit/internal/version"
2427
"github.com/urfave/cli/v3"
2528
)
2629

@@ -59,15 +62,15 @@ func initializeApp() (*cli.Command, error) {
5962
container := di.NewContainer(cfgApp, translations)
6063

6164
if err := container.RegisterAIProvider("gemini", gemini.NewGeminiProviderFactory()); err != nil {
62-
log.Printf("Warning: failed to register Gemini provider: %v", err)
65+
log.Printf("Warning: no se pudo registrar el proveedor Gemini: %v", err)
6366
}
6467

6568
if err := container.RegisterVCSProvider("github", github.NewGitHubProviderFactory()); err != nil {
66-
log.Printf("Warning: failed to register GitHub provider: %v", err)
69+
log.Printf("Warning: no se pudo registrar el proveedor de GitHub: %v", err)
6770
}
6871

6972
if err := container.RegisterTicketProvider("jira", jira.NewJiraProviderFactory()); err != nil {
70-
log.Printf("Warning: failed to register Jira provider: %v", err)
73+
log.Printf("Warning: no se pudo registrar el proveedor Jira: %v", err)
7174
}
7275

7376
gitService := git.NewGitService(translations)
@@ -76,7 +79,7 @@ func initializeApp() (*cli.Command, error) {
7679
ctx := context.Background()
7780
commitService, err := container.GetCommitService(ctx)
7881
if err != nil {
79-
log.Printf("Warning: commit service initialization failed: %v", err)
82+
log.Printf("Warning: la inicialización del servicio de confirmación falló: %v", err)
8083
log.Println("La IA no está configurada. Podés configurarla con 'matecommit config init'")
8184
}
8285

@@ -109,6 +112,10 @@ func initializeApp() (*cli.Command, error) {
109112
log.Fatalf("Error al registrar el comando 'release': %v", err)
110113
}
111114

115+
if err := registerCommand.Register("update", update.NewUpdateCommandFactory("v1.4.0")); err != nil {
116+
log.Fatalf("Error al registrar el comando 'update': %v", err)
117+
}
118+
112119
commands := registerCommand.CreateCommands()
113120
commands = append(commands, completion.NewCompletionCommand(translations))
114121

@@ -122,10 +129,15 @@ func initializeApp() (*cli.Command, error) {
122129
}
123130
commands = append(commands, helpCommand)
124131

132+
go func() {
133+
checker := services.NewVersionUpdater(version.FullVersion(), translations)
134+
checker.CheckForUpdates(context.Background())
135+
}()
136+
125137
return &cli.Command{
126138
Name: "mate-commit",
127139
Usage: translations.GetMessage("app_usage", 0, nil),
128-
Version: "1.4.0",
140+
Version: version.Version,
129141
Description: translations.GetMessage("app_description", 0, nil),
130142
Commands: commands,
131143
EnableShellCompletion: true,

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ toolchain go1.24.5
66

77
require (
88
github.com/BurntSushi/toml v1.5.0
9+
github.com/briandowns/spinner v1.23.0
10+
github.com/fatih/color v1.18.0
911
github.com/google/go-github/v80 v80.0.0
1012
github.com/nicksnyder/go-i18n/v2 v2.6.0
1113
github.com/stretchr/testify v1.11.1
1214
github.com/urfave/cli/v3 v3.6.1
15+
golang.org/x/mod v0.30.0
1316
golang.org/x/oauth2 v0.34.0
1417
golang.org/x/text v0.32.0
1518
google.golang.org/genai v1.38.0
@@ -19,10 +22,8 @@ require (
1922
cloud.google.com/go v0.123.0 // indirect
2023
cloud.google.com/go/auth v0.17.0 // indirect
2124
cloud.google.com/go/compute/metadata v0.9.0 // indirect
22-
github.com/briandowns/spinner v1.23.0 // indirect
2325
github.com/cespare/xxhash/v2 v2.3.0 // indirect
2426
github.com/davecgh/go-spew v1.1.1 // indirect
25-
github.com/fatih/color v1.18.0 // indirect
2627
github.com/felixge/httpsnoop v1.0.4 // indirect
2728
github.com/go-logr/logr v1.4.3 // indirect
2829
github.com/go-logr/stdr v1.2.2 // indirect

go.sum

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,10 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg
88
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
99
github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A=
1010
github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE=
11-
github.com/briandowns/spinner v1.23.2 h1:Zc6ecUnI+YzLmJniCfDNaMbW0Wid1d5+qcTq4L2FW8w=
12-
github.com/briandowns/spinner v1.23.2/go.mod h1:LaZeM4wm2Ywy6vO571mvhQNRcWfRUnXOs0RcKV0wYKM=
1311
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
1412
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
1513
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1614
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
17-
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
18-
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
1915
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
2016
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
2117
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
@@ -48,12 +44,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
4844
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
4945
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
5046
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
51-
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
52-
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
5347
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
5448
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
55-
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
56-
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
5749
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
5850
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
5951
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
@@ -85,13 +77,14 @@ go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6
8577
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
8678
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
8779
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
80+
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
81+
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
8882
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
8983
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
9084
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
9185
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
9286
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
9387
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
94-
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
9588
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9689
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9790
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=

internal/cli/command/handler/suggestions.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ func (h *SuggestionHandler) displaySuggestions(suggestions []models.CommitSugges
4747
suggestionHeader := color.New(color.FgMagenta, color.Bold).Sprintf("📝 Sugerencia #%d", i+1)
4848
fmt.Printf("%s\n\n", suggestionHeader)
4949

50+
if i == 0 && suggestion.Usage != nil {
51+
ui.PrintTokenUsage(suggestion.Usage, h.t)
52+
}
53+
5054
_, _ = sectionColor.Println(h.t.GetMessage("ui_labels.code_analysis", 0, nil))
5155
printIndentedKeyValue(h.t.GetMessage("ui_labels.changes_overview", 0, nil), suggestion.CodeAnalysis.ChangesOverview)
5256
printIndentedKeyValue(h.t.GetMessage("ui_labels.primary_purpose", 0, nil), suggestion.CodeAnalysis.PrimaryPurpose)

internal/cli/command/update/cmd.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package update
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/Tomas-vilte/MateCommit/internal/config"
8+
"github.com/Tomas-vilte/MateCommit/internal/i18n"
9+
"github.com/Tomas-vilte/MateCommit/internal/services"
10+
"github.com/urfave/cli/v3"
11+
)
12+
13+
type UpdateCommandFactory struct {
14+
currentVersion string
15+
}
16+
17+
func NewUpdateCommandFactory(currentVersion string) *UpdateCommandFactory {
18+
return &UpdateCommandFactory{
19+
currentVersion: currentVersion,
20+
}
21+
}
22+
23+
func (f *UpdateCommandFactory) CreateCommand(trans *i18n.Translations, _ *config.Config) *cli.Command {
24+
return &cli.Command{
25+
Name: "update",
26+
Usage: trans.GetMessage("update.usage", 0, nil),
27+
Action: func(ctx context.Context, command *cli.Command) error {
28+
updater := services.NewVersionUpdater(f.currentVersion, trans)
29+
30+
fmt.Println(trans.GetMessage("update.updating", 0, nil))
31+
if err := updater.UpdateCLI(ctx); err != nil {
32+
return err
33+
}
34+
35+
fmt.Println(trans.GetMessage("update.success", 0, nil))
36+
return nil
37+
},
38+
}
39+
}

internal/domain/models/commit.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type (
2828
Files []string
2929
CodeAnalysis CodeAnalysis
3030
RequirementsAnalysis RequirementsAnalysis
31+
Usage *UsageMetadata
3132
}
3233

3334
CodeAnalysis struct {

internal/domain/models/pr.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ type (
2222
Title string
2323
Body string
2424
Labels []string
25+
Usage *UsageMetadata
2526
}
2627
)

internal/domain/models/release.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ type (
8888
BreakingChanges []string
8989
Comparisons []Comparison
9090
Links map[string]string
91+
Usage *UsageMetadata
9192
}
9293

9394
// CodeExample representa un ejemplo de código con descripción

internal/domain/models/usage.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package models
2+
3+
type UsageMetadata struct {
4+
InputTokens int
5+
OutputTokens int
6+
TotalTokens int
7+
}

internal/infrastructure/ai/gemini/commit_summarizer_service.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,16 @@ func (s *GeminiService) GenerateSuggestions(ctx context.Context, info models.Com
108108
respLen, err, preview)
109109
}
110110

111+
usage := extractUsage(resp)
112+
111113
if len(suggestions) == 0 {
112114
return nil, fmt.Errorf("la IA no generó ninguna sugerencia")
113115
}
114116

117+
for i := range suggestions {
118+
suggestions[i].Usage = usage
119+
}
120+
115121
if info.IssueInfo != nil && info.IssueInfo.Number > 0 {
116122
suggestions = s.ensureIssueReference(suggestions, info.IssueInfo.Number)
117123
}

0 commit comments

Comments
 (0)