Skip to content

Commit ad8c000

Browse files
authored
upgrade bubbletea and lipgloss to v2 (#233)
- Update module paths from github.com/charmbracelet/{bubbletea,lipgloss} to charm.land/{bubbletea,lipgloss}/v2 v2.0.5 / v2.0.3 - Update all import paths across TUI files - Migrate Model.View() return type from string to tea.View (via tea.NewView) - Replace tea.WithAltScreen() with v.AltScreen = true on the returned View - Replace tea.KeyMsg struct type-switch on msg.Type with tea.KeyPressMsg and msg.Key().Code; handle ctrl+c and ctrl+z via msg.String()
1 parent 9436ef4 commit ad8c000

11 files changed

Lines changed: 115 additions & 110 deletions

File tree

actions/view.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import (
1515
"github.com/cego/gitte/executor"
1616
"github.com/cego/gitte/output"
1717

18-
tea "github.com/charmbracelet/bubbletea"
19-
"github.com/charmbracelet/lipgloss"
18+
tea "charm.land/bubbletea/v2"
19+
"charm.land/lipgloss/v2"
2020
"golang.org/x/term"
2121
)
2222

@@ -779,7 +779,7 @@ func (m *actionsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
779779
m.updateCollapsed()
780780
return m, m.listen()
781781

782-
case tea.KeyMsg:
782+
case tea.KeyPressMsg:
783783
// Route all key events to the quick solve overlay when it is active.
784784
if m.quickSolve != nil {
785785
return m.updateQuickSolve(msg)
@@ -860,7 +860,7 @@ func (m *actionsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
860860
}
861861

862862
// updateQuickSolve handles key events while the quick solve overlay is open.
863-
func (m *actionsModel) updateQuickSolve(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
863+
func (m *actionsModel) updateQuickSolve(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) {
864864
qs := m.quickSolve
865865
switch qs.step {
866866
case qsStepMenu:
@@ -1062,12 +1062,12 @@ var (
10621062

10631063
var actSpinFrames = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
10641064

1065-
func (m *actionsModel) View() string {
1065+
func (m *actionsModel) View() tea.View {
10661066
if m.width == 0 {
1067-
return "Loading...\n"
1067+
return tea.NewView("Loading...\n")
10681068
}
10691069
if m.quickSolve != nil {
1070-
return m.renderQuickSolveView()
1070+
return tea.NewView(m.renderQuickSolveView())
10711071
}
10721072

10731073
leftW := 48
@@ -1173,7 +1173,7 @@ func (m *actionsModel) View() string {
11731173
}
11741174
b.WriteString(actHelpStyle.Render(strings.Join(parts, " ")))
11751175

1176-
return b.String()
1176+
return tea.NewView(b.String())
11771177
}
11781178

11791179
// renderQuickSolveView renders the full screen with the quick solve modal overlaying the body.

cmd/clean_view.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import (
66
"strings"
77
"time"
88

9-
tea "github.com/charmbracelet/bubbletea"
10-
"github.com/charmbracelet/lipgloss"
9+
tea "charm.land/bubbletea/v2"
10+
"charm.land/lipgloss/v2"
1111

1212
"github.com/cego/gitte/output"
1313
)
@@ -168,7 +168,7 @@ func (m *cleanModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
168168
return m, nil
169169
}
170170

171-
func (m *cleanModel) View() string {
171+
func (m *cleanModel) View() tea.View {
172172
var b strings.Builder
173173
width := m.width
174174
if width <= 0 {
@@ -206,7 +206,9 @@ func (m *cleanModel) View() string {
206206
b.WriteString("\n")
207207
}
208208

209-
return b.String()
209+
v := tea.NewView(b.String())
210+
v.AltScreen = true
211+
return v
210212
}
211213

212214
func renderPhaseHeader(title string, width int) string {
@@ -342,7 +344,7 @@ func newCleanView(mode output.OutputMode, specs []cleanPhaseSpec) *cleanView {
342344
}
343345
msgCh := make(chan cleanMsg, 100)
344346
m := newCleanModel(specs, msgCh)
345-
p := tea.NewProgram(m, tea.WithAltScreen())
347+
p := tea.NewProgram(m)
346348
v.program = p
347349
v.msgCh = msgCh
348350
v.doneCh = make(chan error, 1)
@@ -415,6 +417,6 @@ func (v *cleanView) Wait() {
415417
close(v.msgCh)
416418
<-v.doneCh
417419
if v.finalModel != nil {
418-
fmt.Print(v.finalModel.View())
420+
fmt.Print(v.finalModel.View().Content)
419421
}
420422
}

cmd/list.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"github.com/cego/gitte/config"
99
"github.com/cego/gitte/output"
1010

11-
"github.com/charmbracelet/lipgloss"
11+
"charm.land/lipgloss/v2"
1212
"github.com/spf13/cobra"
1313
)
1414

cmd/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
"github.com/cego/gitte/output"
1515
"github.com/cego/gitte/state"
1616

17-
"github.com/charmbracelet/lipgloss"
17+
"charm.land/lipgloss/v2"
1818
"github.com/spf13/cobra"
1919
)
2020

features/tui.go

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import (
99
"github.com/cego/gitte/config"
1010
"github.com/cego/gitte/state"
1111

12-
tea "github.com/charmbracelet/bubbletea"
13-
"github.com/charmbracelet/lipgloss"
12+
tea "charm.land/bubbletea/v2"
13+
"charm.land/lipgloss/v2"
1414
)
1515

1616
type screen int
@@ -231,7 +231,7 @@ func (m *featuresModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
231231
m.height = msg.Height
232232
return m, nil
233233

234-
case tea.KeyMsg:
234+
case tea.KeyPressMsg:
235235
if m.screen == screenGateList {
236236
return m.updateGateList(msg)
237237
}
@@ -241,16 +241,21 @@ func (m *featuresModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
241241
}
242242

243243
// View renders the current screen.
244-
func (m *featuresModel) View() string {
244+
func (m *featuresModel) View() tea.View {
245+
var s string
245246
if m.screen == screenScopeTree {
246-
return m.viewScopeTree()
247+
s = m.viewScopeTree()
248+
} else {
249+
s = m.viewGateList()
247250
}
248-
return m.viewGateList()
251+
v := tea.NewView(s)
252+
v.AltScreen = true
253+
return v
249254
}
250255

251-
func (m *featuresModel) updateGateList(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
252-
switch msg.Type {
253-
case tea.KeyCtrlC, tea.KeyEsc:
256+
func (m *featuresModel) updateGateList(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) {
257+
switch msg.Key().Code {
258+
case tea.KeyEsc:
254259
m.save()
255260
return m, tea.Quit
256261
case tea.KeyUp:
@@ -271,7 +276,7 @@ func (m *featuresModel) updateGateList(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
271276
}
272277
default:
273278
switch msg.String() {
274-
case "q":
279+
case "ctrl+c", "q":
275280
m.save()
276281
return m, tea.Quit
277282
case "k":
@@ -287,12 +292,8 @@ func (m *featuresModel) updateGateList(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
287292
return m, nil
288293
}
289294

290-
func (m *featuresModel) updateScopeTree(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
291-
switch msg.Type {
292-
case tea.KeyCtrlC:
293-
m.applyScopeChanges()
294-
m.save()
295-
return m, tea.Quit
295+
func (m *featuresModel) updateScopeTree(msg tea.KeyPressMsg) (tea.Model, tea.Cmd) {
296+
switch msg.Key().Code {
296297
case tea.KeyEsc:
297298
m.applyScopeChanges()
298299
m.screen = screenGateList
@@ -307,14 +308,14 @@ func (m *featuresModel) updateScopeTree(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
307308
m.scopeMoveNextPage()
308309
case tea.KeySpace, tea.KeyEnter:
309310
m.scopeToggle()
310-
case tea.KeyCtrlZ:
311-
m.scopeUndo()
312311
default:
313312
switch msg.String() {
314-
case "q":
313+
case "ctrl+c", "q":
315314
m.applyScopeChanges()
316315
m.save()
317316
return m, tea.Quit
317+
case "ctrl+z":
318+
m.scopeUndo()
318319
case "k":
319320
m.scopeMovePrev()
320321
case "j":
@@ -554,7 +555,7 @@ func Run(cfg *config.GitteConfig, cwd string, st *state.GitteState) error {
554555
return ErrNoFeatureGates
555556
}
556557
model := newFeaturesModel(cfg, cwd, st)
557-
p := tea.NewProgram(model, tea.WithAltScreen())
558+
p := tea.NewProgram(model)
558559
_, err := p.Run()
559560
return err
560561
}

gitops/view.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
"sync"
99
"time"
1010

11-
tea "github.com/charmbracelet/bubbletea"
12-
"github.com/charmbracelet/lipgloss"
11+
tea "charm.land/bubbletea/v2"
12+
"charm.land/lipgloss/v2"
1313

1414
"github.com/cego/gitte/output"
1515
)
@@ -281,7 +281,7 @@ func (m *gitopsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
281281
m.width = msg.Width
282282
m.height = msg.Height
283283

284-
case tea.KeyMsg:
284+
case tea.KeyPressMsg:
285285
if msg.String() == "ctrl+c" {
286286
if m.cancel != nil {
287287
m.cancel()
@@ -363,7 +363,7 @@ func (m *gitopsModel) progressMode() bool {
363363
return len(m.entries) > available*nCols
364364
}
365365

366-
func (m *gitopsModel) View() string {
366+
func (m *gitopsModel) View() tea.View {
367367
var b strings.Builder
368368
title := m.title
369369
if title == "" {
@@ -385,7 +385,7 @@ func (m *gitopsModel) View() string {
385385

386386
if m.progressMode() {
387387
b.WriteString(m.renderProgressBar(width) + "\n")
388-
return b.String()
388+
return tea.NewView(b.String())
389389
}
390390

391391
const minColW = 60
@@ -415,7 +415,7 @@ func (m *gitopsModel) View() string {
415415
b.WriteString("\n")
416416
}
417417

418-
return b.String()
418+
return tea.NewView(b.String())
419419
}
420420

421421
func (m *gitopsModel) renderProgressBar(width int) string {

go.mod

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ module github.com/cego/gitte
33
go 1.25.0
44

55
require (
6-
github.com/charmbracelet/bubbletea v1.3.10
7-
github.com/charmbracelet/lipgloss v1.1.0
6+
charm.land/bubbletea/v2 v2.0.5
7+
charm.land/lipgloss/v2 v2.0.3
88
github.com/goccy/go-yaml v1.19.2
99
github.com/joho/godotenv v1.5.1
1010
github.com/samber/lo v1.53.0
@@ -15,25 +15,24 @@ require (
1515
)
1616

1717
require (
18-
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
19-
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
20-
github.com/charmbracelet/x/ansi v0.10.1 // indirect
21-
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
22-
github.com/charmbracelet/x/term v0.2.1 // indirect
18+
github.com/charmbracelet/colorprofile v0.4.3 // indirect
19+
github.com/charmbracelet/ultraviolet v0.0.0-20260413211237-bd52878bcec2 // indirect
20+
github.com/charmbracelet/x/ansi v0.11.7 // indirect
21+
github.com/charmbracelet/x/term v0.2.2 // indirect
22+
github.com/charmbracelet/x/termios v0.1.1 // indirect
23+
github.com/charmbracelet/x/windows v0.2.2 // indirect
24+
github.com/clipperhouse/displaywidth v0.11.0 // indirect
25+
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
2326
github.com/danieljoos/wincred v1.2.3 // indirect
24-
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
2527
github.com/godbus/dbus/v5 v5.2.2 // indirect
2628
github.com/inconshreveable/mousetrap v1.1.0 // indirect
27-
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
28-
github.com/mattn/go-isatty v0.0.20 // indirect
29-
github.com/mattn/go-localereader v0.0.1 // indirect
30-
github.com/mattn/go-runewidth v0.0.16 // indirect
31-
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
29+
github.com/lucasb-eyer/go-colorful v1.4.0 // indirect
30+
github.com/mattn/go-runewidth v0.0.23 // indirect
3231
github.com/muesli/cancelreader v0.2.2 // indirect
33-
github.com/muesli/termenv v0.16.0 // indirect
3432
github.com/rivo/uniseg v0.4.7 // indirect
3533
github.com/spf13/pflag v1.0.9 // indirect
3634
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
35+
golang.org/x/sync v0.20.0 // indirect
3736
golang.org/x/sys v0.43.0 // indirect
3837
golang.org/x/text v0.22.0 // indirect
3938
)

0 commit comments

Comments
 (0)