Skip to content

Commit 5d831ec

Browse files
committed
fix: improve bumpver ux
1 parent f35312f commit 5d831ec

File tree

6 files changed

+157
-192
lines changed

6 files changed

+157
-192
lines changed

internal/cli/bumpver.go

+11-10
Original file line numberDiff line numberDiff line change
@@ -76,29 +76,31 @@ func runBumpVer(cmd *cobra.Command, opts bumpVerOpts) error {
7676
return err
7777
}
7878

79-
changelog, err := changelog.RunChangelog()
79+
changelogModel, err := changelog.RunChangelog(cmd.InOrStdin(), cmd.OutOrStdout())
8080
if err != nil {
8181
return err
8282
}
8383

84-
switch changelog.Increment {
85-
case "patch":
84+
switch changelogModel.Increment {
85+
case changelog.Patch:
8686
newVer = currentVer.IncPatch()
87-
case "minor":
87+
case changelog.Minor:
8888
newVer = currentVer.IncMinor()
89-
case "major":
89+
case changelog.Major:
9090
newVer = currentVer.IncMajor()
9191
}
9292

93-
changelogMsg = changelog.Msg
93+
changelogMsg = changelogModel.Msg
9494

9595
} else {
9696
optVer, err := semver.NewVersion(opts.RecipeVersion)
9797
if err != nil {
98-
if errors.Is(err, semver.ErrInvalidSemVer) {
98+
switch {
99+
case errors.Is(err, semver.ErrInvalidSemVer):
99100
return fmt.Errorf("provided version is not valid semver: %s", opts.RecipeVersion)
101+
default:
102+
return err
100103
}
101-
return err
102104
}
103105

104106
newVer = *optVer
@@ -115,8 +117,7 @@ func runBumpVer(cmd *cobra.Command, opts bumpVerOpts) error {
115117
return err
116118
}
117119

118-
cmd.Printf("bumped version: %s => %s \n", prevVer, newVerWithPrefix)
119-
cmd.Printf("with changelog message: %s \n", changelogMsg)
120+
cmd.Printf("Recipe version bumped: %s => %s \n", prevVer, newVerWithPrefix)
120121

121122
return nil
122123
}

pkg/ui/changelog/changelog.go

+30-12
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,31 @@ package changelog
33
import (
44
"errors"
55
"fmt"
6+
"io"
67

78
tea "github.com/charmbracelet/bubbletea"
8-
changelog "github.com/futurice/jalapeno/pkg/ui/changelog/prompt"
9+
"github.com/futurice/jalapeno/pkg/ui/util"
10+
)
11+
12+
const (
13+
Patch = "patch"
14+
Minor = "minor"
15+
Major = "major"
916
)
1017

1118
type Changelog struct {
1219
Increment string
1320
Msg string
1421
}
1522

16-
func RunChangelog() (Changelog, error) {
17-
verInc, err := runSelectPrompt()
23+
func RunChangelog(in io.Reader, out io.Writer) (Changelog, error) {
24+
verInc, err := runVersionPrompt(in, out)
1825

1926
if err != nil {
2027
return Changelog{}, fmt.Errorf("failed to get version type: %w", err)
2128
}
2229

23-
logmsg, err := runTextAreaPrompt()
30+
logmsg, err := runMessagePrompt(in, out)
2431

2532
if err != nil {
2633
return Changelog{}, fmt.Errorf("failed to get log message: %w", err)
@@ -34,32 +41,43 @@ func RunChangelog() (Changelog, error) {
3441
return changelog, nil
3542
}
3643

37-
func runSelectPrompt() (string, error) {
38-
options := []string{"patch", "minor", "major"}
44+
func runVersionPrompt(in io.Reader, out io.Writer) (string, error) {
45+
options := []string{Patch, Minor, Major}
3946

40-
p := tea.NewProgram(changelog.NewSelectModel(options))
47+
p := tea.NewProgram(NewSelectModel(options), tea.WithInput(in), tea.WithOutput(out))
4148

4249
if m, err := p.Run(); err != nil {
4350
return "", err
4451
} else {
45-
sel, ok := m.(changelog.SelectModel)
52+
sel, ok := m.(VersionModel)
4653
if !ok {
4754
return "", errors.New("internal error: unexpected model type")
4855
}
49-
return sel.Value(), nil
56+
value := sel.Value()
57+
if value == "" {
58+
return "", util.ErrUserAborted
59+
}
60+
61+
return value, nil
5062
}
5163
}
5264

53-
func runTextAreaPrompt() (string, error) {
54-
p := tea.NewProgram(changelog.NewStringModel())
65+
func runMessagePrompt(in io.Reader, out io.Writer) (string, error) {
66+
p := tea.NewProgram(NewStringModel(), tea.WithInput(in), tea.WithOutput(out))
5567

5668
if m, err := p.Run(); err != nil {
5769
return "", err
5870
} else {
59-
txt, ok := m.(changelog.StringModel)
71+
txt, ok := m.(MessageModel)
6072
if !ok {
6173
return "", errors.New("internal error: unexpected model type")
6274
}
75+
76+
value := txt.Value()
77+
if value == "" {
78+
return "", util.ErrUserAborted
79+
}
80+
6381
return txt.Value(), nil
6482
}
6583
}

pkg/ui/changelog/message_prompt.go

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package changelog
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"strings"
7+
8+
"github.com/charmbracelet/bubbles/textarea"
9+
"github.com/charmbracelet/bubbles/textinput"
10+
tea "github.com/charmbracelet/bubbletea"
11+
"github.com/futurice/jalapeno/pkg/ui/colors"
12+
"github.com/muesli/reflow/wordwrap"
13+
)
14+
15+
type MessageModel struct {
16+
textArea textarea.Model
17+
width int
18+
err error
19+
}
20+
21+
var _ tea.Model = MessageModel{}
22+
23+
func NewStringModel() MessageModel {
24+
ti := textarea.New()
25+
ti.Focus()
26+
ti.SetHeight(5)
27+
ti.CharLimit = 156
28+
29+
return MessageModel{
30+
textArea: ti,
31+
err: nil,
32+
}
33+
}
34+
35+
func (m MessageModel) Init() tea.Cmd {
36+
return textinput.Blink
37+
}
38+
39+
func (m MessageModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
40+
var cmd tea.Cmd
41+
42+
switch msg := msg.(type) {
43+
case tea.KeyMsg:
44+
switch msg.Type {
45+
case tea.KeyCtrlC, tea.KeyEsc:
46+
return m, tea.Quit
47+
case tea.KeyCtrlS:
48+
m.err = m.Validate()
49+
if m.err == nil {
50+
return m, tea.Quit
51+
}
52+
return m, nil
53+
}
54+
55+
case tea.WindowSizeMsg:
56+
m.width = msg.Width
57+
m.textArea.SetWidth(m.width)
58+
}
59+
60+
m.textArea, cmd = m.textArea.Update(msg)
61+
return m, cmd
62+
}
63+
64+
func (m MessageModel) View() string {
65+
var s strings.Builder
66+
67+
s.WriteString(wordwrap.String("Write the changelog message for the new version", m.width))
68+
s.WriteString("\nPress Ctrl+S to save")
69+
s.WriteRune('\n')
70+
71+
s.WriteString(m.textArea.View())
72+
73+
if m.err != nil {
74+
s.WriteString("\n\n")
75+
s.WriteString(colors.Red.Render(fmt.Sprintf("Error: %s", m.err.Error())))
76+
}
77+
78+
s.WriteString("\n\n")
79+
80+
return s.String()
81+
}
82+
83+
func (m MessageModel) Value() string {
84+
return strings.TrimSpace(m.textArea.Value())
85+
}
86+
87+
func (m MessageModel) Validate() error {
88+
if m.textArea.Value() == "" {
89+
return errors.New("changelog message cannot be empty")
90+
}
91+
92+
return nil
93+
}

pkg/ui/changelog/prompt/textarea.go

-124
This file was deleted.

0 commit comments

Comments
 (0)