Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func initializeApp() (*cli.Command, error) {
return issueService, nil
}
commands := []*cli.Command{
suggests_commits.NewSuggestCommandFactory(commitService, commitHandler).CreateCommand(translations, cfgApp),
suggests_commits.NewSuggestCommandFactory(commitService, commitHandler, gitService).CreateCommand(translations, cfgApp),
issues.NewIssuesCommandFactory(
issueProvider,
templateService,
Expand Down
9 changes: 8 additions & 1 deletion internal/commands/release/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ func createReleaseAction(releaseSvc releaseService, trans *i18n.Translations, re
fmt.Println(trans.GetMessage("release.creating", 0, nil))
fmt.Println()

if err := releaseSvc.ValidateMainBranch(ctx); err != nil {
log.Error("branch validation failed",
"error", err,
)
return fmt.Errorf("%s", trans.GetMessage("release.error_invalid_branch", 0, struct{ Error string }{err.Error()}))
}

release, err := releaseSvc.AnalyzeNextRelease(ctx)
if err != nil {
log.Error("failed to analyze next release",
Expand Down Expand Up @@ -139,7 +146,7 @@ func createReleaseAction(releaseSvc releaseService, trans *i18n.Translations, re

sVersion := ui.NewSmartSpinner(trans.GetMessage("release.app_version_update_started", 0, struct{ Version string }{release.Version}))
sVersion.Start()
if err := releaseSvc.UpdateAppVersion(release.Version); err != nil {
if err := releaseSvc.UpdateAppVersion(ctx, release.Version); err != nil {
sVersion.Error(trans.GetMessage("release.error_updating_app_version", 0, struct{ Error string }{err.Error()}))
return fmt.Errorf("error updating app version: %w", err)
}
Expand Down
20 changes: 14 additions & 6 deletions internal/commands/release/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
"errors"
"testing"

"github.com/thomas-vilte/matecommit/internal/models"
"github.com/thomas-vilte/matecommit/internal/i18n"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/thomas-vilte/matecommit/internal/i18n"
"github.com/thomas-vilte/matecommit/internal/models"
"github.com/urfave/cli/v3"
)

Expand Down Expand Up @@ -63,6 +63,7 @@ func TestCreateCommand_Success(t *testing.T) {
}

mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
mockService.On("CreateTag", mock.Anything, "v1.1.0", "Release v1.1.0\n\nSummary of release").Return(nil)
Expand All @@ -85,6 +86,7 @@ func TestCreateCommand_WithVersionOverride(t *testing.T) {
Title: "Release v2.0.0",
}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, mock.MatchedBy(func(r *models.Release) bool {
Expand All @@ -103,6 +105,7 @@ func TestCreateCommand_AutoConfirm(t *testing.T) {
release := &models.Release{Version: "v1.0.1"}
notes := &models.ReleaseNotes{Title: "Fix"}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
Expand All @@ -117,6 +120,7 @@ func TestCreateCommand_Cancelled(t *testing.T) {
release := &models.Release{Version: "v1.0.1"}
notes := &models.ReleaseNotes{Title: "Fix"}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
Expand All @@ -128,6 +132,7 @@ func TestCreateCommand_Cancelled(t *testing.T) {

func TestCreateCommand_AnalyzeError(t *testing.T) {
mockService := new(MockReleaseService)
mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return((*models.Release)(nil), errors.New("git error"))
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)

Expand All @@ -140,6 +145,7 @@ func TestCreateCommand_AnalyzeError(t *testing.T) {
func TestCreateCommand_GenerateNotesError(t *testing.T) {
mockService := new(MockReleaseService)
release := &models.Release{Version: "v1.0.0"}
mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return((*models.ReleaseNotes)(nil), errors.New("ai error"))
Expand All @@ -156,6 +162,7 @@ func TestCreateCommand_CreateTagError(t *testing.T) {
release := &models.Release{Version: "v1.0.0"}
notes := &models.ReleaseNotes{Title: "Title"}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
Expand All @@ -173,12 +180,12 @@ func TestCreateCommand_WithPublish(t *testing.T) {
release := &models.Release{Version: "v1.0.0"}
notes := &models.ReleaseNotes{Title: "Title"}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
mockService.On("CreateTag", mock.Anything, "v1.0.0", mock.Anything).Return(nil)

// Expect PublishRelease with buildBinaries=true (default)
mockService.On("PublishRelease", mock.Anything, release, notes, false, true).Return(nil)

err := runCreateTest(t, "y\n", []string{"--publish"}, mockService)
Expand All @@ -192,12 +199,12 @@ func TestCreateCommand_WithPublishDraft(t *testing.T) {
release := &models.Release{Version: "v1.0.0"}
notes := &models.ReleaseNotes{Title: "Title"}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
mockService.On("CreateTag", mock.Anything, "v1.0.0", mock.Anything).Return(nil)

// Expect PublishRelease with draft=true and buildBinaries=true (default)
mockService.On("PublishRelease", mock.Anything, release, notes, true, true).Return(nil)

err := runCreateTest(t, "y\n", []string{"--publish", "--draft"}, mockService)
Expand All @@ -211,12 +218,12 @@ func TestCreateCommand_PublishError(t *testing.T) {
release := &models.Release{Version: "v1.0.0"}
notes := &models.ReleaseNotes{Title: "Title"}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
mockService.On("CreateTag", mock.Anything, "v1.0.0", mock.Anything).Return(nil)

// Expect PublishRelease error
mockService.On("PublishRelease", mock.Anything, release, notes, false, true).Return(errors.New("publish error"))

err := runCreateTest(t, "y\n", []string{"--publish"}, mockService)
Expand All @@ -229,12 +236,13 @@ func TestCreateCommand_WithChangelog(t *testing.T) {
release := &models.Release{Version: "v1.0.0"}
notes := &models.ReleaseNotes{Title: "Title"}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)

mockService.On("UpdateLocalChangelog", release, notes).Return(nil)
mockService.On("UpdateAppVersion", "v1.0.0").Return(nil)
mockService.On("UpdateAppVersion", mock.Anything, "v1.0.0").Return(nil)
mockService.On("CommitChangelog", mock.Anything, "v1.0.0").Return(nil)
mockService.On("PushChanges", mock.Anything).Return(nil)

Expand Down
6 changes: 6 additions & 0 deletions internal/commands/release/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ func generateReleaseAction(releaseSvc releaseService, trans *i18n.Translations)
fmt.Println(trans.GetMessage("release.generating", 0, nil))
fmt.Println()

if err := releaseSvc.ValidateMainBranch(ctx); err != nil {
log.Error("branch validation failed",
"error", err)
return fmt.Errorf("%s", trans.GetMessage("release.error_invalid_branch", 0, struct{ Error string }{err.Error()}))
}

release, err := releaseSvc.AnalyzeNextRelease(ctx)
if err != nil {
log.Error("failed to analyze next release",
Expand Down
8 changes: 6 additions & 2 deletions internal/commands/release/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
"path/filepath"
"testing"

"github.com/thomas-vilte/matecommit/internal/models"
"github.com/thomas-vilte/matecommit/internal/i18n"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/thomas-vilte/matecommit/internal/i18n"
"github.com/thomas-vilte/matecommit/internal/models"
"github.com/urfave/cli/v3"
)

Expand Down Expand Up @@ -55,6 +55,7 @@ func TestGenerateCommand_Success(t *testing.T) {
Highlights: []string{"Highlight 1"},
}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
Expand All @@ -75,6 +76,7 @@ func TestGenerateCommand_Success(t *testing.T) {

func TestGenerateCommand_AnalyzeError(t *testing.T) {
mockService := new(MockReleaseService)
mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return((*models.Release)(nil), errors.New("git error"))
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)

Expand All @@ -88,6 +90,7 @@ func TestGenerateCommand_AnalyzeError(t *testing.T) {
func TestGenerateCommand_GenerateError(t *testing.T) {
mockService := new(MockReleaseService)
release := &models.Release{Version: "v1.0.0"}
mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return((*models.ReleaseNotes)(nil), errors.New("ai error"))
Expand All @@ -104,6 +107,7 @@ func TestGenerateCommand_WriteError(t *testing.T) {
release := &models.Release{Version: "v1.0.0"}
notes := &models.ReleaseNotes{Title: "Title"}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
Expand Down
26 changes: 23 additions & 3 deletions internal/commands/release/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package release
import (
"context"

"github.com/thomas-vilte/matecommit/internal/models"
"github.com/stretchr/testify/mock"
"github.com/thomas-vilte/matecommit/internal/models"
)

type MockReleaseService struct {
Expand Down Expand Up @@ -75,8 +75,8 @@ func (m *MockReleaseService) PushChanges(ctx context.Context) error {
return args.Error(0)
}

func (m *MockReleaseService) UpdateAppVersion(version string) error {
args := m.Called(version)
func (m *MockReleaseService) UpdateAppVersion(ctx context.Context, version string) error {
args := m.Called(ctx, version)
return args.Error(0)
}

Expand Down Expand Up @@ -169,3 +169,23 @@ func (m *MockGitService) GetRecentCommitMessages(ctx context.Context, count int)
args := m.Called(ctx, count)
return args.Get(0).([]string), args.Error(1)
}

func (m *MockReleaseService) ValidateMainBranch(ctx context.Context) error {
args := m.Called(ctx)
return args.Error(0)
}

func (m *MockGitService) FetchTags(ctx context.Context) error {
args := m.Called(ctx)
return args.Error(0)
}

func (m *MockGitService) ValidateGitConfig(ctx context.Context) error {
args := m.Called(ctx)
return args.Error(0)
}

func (m *MockGitService) ValidateTagExists(ctx context.Context, tag string) error {
args := m.Called(ctx, tag)
return args.Error(0)
}
6 changes: 6 additions & 0 deletions internal/commands/release/preview.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ func previewReleaseAction(releaseSvc releaseService, trans *i18n.Translations) c
fmt.Println(trans.GetMessage("release.analyzing", 0, nil))
fmt.Println()

if err := releaseSvc.ValidateMainBranch(ctx); err != nil {
log.Error("branch validation failed",
"error", err)
return fmt.Errorf("%s", trans.GetMessage("release.error_invalid_branch", 0, struct{ Error string }{err.Error()}))
}

release, err := releaseSvc.AnalyzeNextRelease(ctx)
if err != nil {
log.Error("failed to analyze next release",
Expand Down
7 changes: 5 additions & 2 deletions internal/commands/release/preview_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import (
"errors"
"testing"

"github.com/thomas-vilte/matecommit/internal/models"
"github.com/thomas-vilte/matecommit/internal/i18n"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/thomas-vilte/matecommit/internal/i18n"
"github.com/thomas-vilte/matecommit/internal/models"
"github.com/urfave/cli/v3"
)

Expand Down Expand Up @@ -50,6 +50,7 @@ func TestPreviewCommand_Success(t *testing.T) {
Highlights: []string{"highlight"},
}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
Expand All @@ -62,6 +63,7 @@ func TestPreviewCommand_Success(t *testing.T) {

func TestPreviewCommand_AnalyzeError(t *testing.T) {
mockService := new(MockReleaseService)
mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return((*models.Release)(nil), errors.New("git error"))
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)

Expand All @@ -75,6 +77,7 @@ func TestPreviewCommand_AnalyzeError(t *testing.T) {
func TestPreviewCommand_GenerateError(t *testing.T) {
mockService := new(MockReleaseService)
release := &models.Release{Version: "v1.0.0"}
mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return((*models.ReleaseNotes)(nil), errors.New("ai error"))
Expand Down
9 changes: 8 additions & 1 deletion internal/commands/release/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,14 @@ func publishReleaseAction(releaseSvc releaseService,
log.Info("executing release publish command",
"version", version,
"draft", draft,
"build_binaries", buildBinaries)
"build_binaries", buildBinaries,
)

if err := releaseSvc.ValidateMainBranch(ctx); err != nil {
log.Error("branch validation failed",
"error", err)
return fmt.Errorf("%s", trans.GetMessage("release.error_invalid_branch", 0, struct{ Error string }{err.Error()}))
}

release, err := releaseSvc.AnalyzeNextRelease(ctx)
if err != nil {
Expand Down
10 changes: 8 additions & 2 deletions internal/commands/release/publish_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import (
"errors"
"testing"

"github.com/thomas-vilte/matecommit/internal/models"
"github.com/thomas-vilte/matecommit/internal/i18n"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/thomas-vilte/matecommit/internal/i18n"
"github.com/thomas-vilte/matecommit/internal/models"
"github.com/urfave/cli/v3"
)

Expand Down Expand Up @@ -53,6 +53,7 @@ func TestPublishCommand_Success(t *testing.T) {
Summary: "Major release",
}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
Expand All @@ -78,6 +79,7 @@ func TestPublishCommand_WithDraftFlag(t *testing.T) {
Summary: "Major release",
}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
Expand All @@ -103,6 +105,7 @@ func TestPublishCommand_WithVersionOverride(t *testing.T) {
Summary: "Major release",
}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, mock.MatchedBy(func(r *models.Release) bool {
Expand All @@ -121,6 +124,7 @@ func TestPublishCommand_WithVersionOverride(t *testing.T) {
func TestPublishCommand_AnalyzeError(t *testing.T) {
mockService := new(MockReleaseService)

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return((*models.Release)(nil), errors.New("analyze failed"))

err := runPublishTest(t, []string{}, mockService)
Expand All @@ -139,6 +143,7 @@ func TestPublishCommand_GenerateNotesError(t *testing.T) {
VersionBump: models.MinorBump,
}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return((*models.ReleaseNotes)(nil), errors.New("generate failed"))
Expand All @@ -164,6 +169,7 @@ func TestPublishCommand_PublishError(t *testing.T) {
Summary: "Major release",
}

mockService.On("ValidateMainBranch", mock.Anything, mock.Anything).Return(nil)
mockService.On("AnalyzeNextRelease", mock.Anything).Return(release, nil)
mockService.On("EnrichReleaseContext", mock.Anything, mock.Anything).Return(nil)
mockService.On("GenerateReleaseNotes", mock.Anything, release).Return(notes, nil)
Expand Down
Loading
Loading