Skip to content

Commit 4a654b5

Browse files
committed
chore: Addressing lints
1 parent 14cac1e commit 4a654b5

8 files changed

Lines changed: 348 additions & 250 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package redesign_test
2+
3+
import "errors"
4+
5+
// failingWriter always returns an error from Write, for exercising
6+
// write-failure branches.
7+
type failingWriter struct{}
8+
9+
func (failingWriter) Write(_ []byte) (int, error) {
10+
return 0, errors.New("write failed")
11+
}

internal/cli/commands/catalog/tui/redesign/model.go

Lines changed: 115 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,6 @@ var (
4343
availableButtons = []button{scaffoldBtn, viewSourceBtn}
4444
)
4545

46-
func (b button) String() string {
47-
return []string{
48-
"Scaffold",
49-
"View Source in Browser",
50-
}[b]
51-
}
52-
5346
type Model struct {
5447
lists [numTabs]list.Model
5548
logger log.Logger
@@ -73,25 +66,6 @@ type Model struct {
7366
userNavigated bool
7467
}
7568

76-
// ExitMessage returns the styled post-exit message the model set while
77-
// handling its final action (e.g., a successful copy that generated a
78-
// terragrunt.values.hcl file). The caller is responsible for printing it
79-
// after the tea.Program returns, once the alt screen has been torn down.
80-
func (m Model) ExitMessage() string { //nolint:gocritic
81-
return m.exitMessage
82-
}
83-
84-
// List returns the currently active list — the one filtered by the active
85-
// tab. Exposed for tests and view code that need to inspect items.
86-
func (m Model) List() list.Model { //nolint:gocritic
87-
return m.lists[m.activeTab]
88-
}
89-
90-
// ActiveTab returns which of the All/Modules/Templates tabs is focused.
91-
func (m Model) ActiveTab() tabKind { //nolint:gocritic
92-
return m.activeTab
93-
}
94-
9569
// NewModelStreaming creates a Model with a single initial entry and a channel
9670
// for receiving additional entries as they are discovered.
9771
func NewModelStreaming(l log.Logger, opts *options.TerragruntOptions, initial *ComponentEntry, componentCh chan *ComponentEntry) Model {
@@ -103,79 +77,48 @@ func NewModelStreaming(l log.Logger, opts *options.TerragruntOptions, initial *C
10377
return m
10478
}
10579

106-
func newModelWithItems(l log.Logger, opts *options.TerragruntOptions, items []list.Item, componentCh chan *ComponentEntry) Model {
107-
listKeys := tui.NewListKeyMap()
108-
delegateKeys := tui.NewDelegateKeyMap()
109-
pagerKeys := tui.NewPagerKeyMap()
110-
111-
delegate := newCatalogDelegate(delegateKeys)
112-
113-
titleStyle := lipgloss.NewStyle().
114-
Foreground(lipgloss.Color(titleForegroundColor)).
115-
Background(lipgloss.Color(titleBackgroundColor)).
116-
Padding(0, 1)
117-
118-
var lists [numTabs]list.Model
119-
120-
for i := range int(numTabs) {
121-
t := tabKind(i)
80+
// NewModelWithExitMessageForTest constructs a Model carrying only an exit
81+
// message, for tests that exercise post-exit message emission without
82+
// standing up the full catalog list state.
83+
func NewModelWithExitMessageForTest(msg string) Model {
84+
return Model{exitMessage: msg}
85+
}
12286

123-
tabItems := filterItemsByTab(items, t)
87+
// ActiveTab returns which of the All/Modules/Templates tabs is focused.
88+
func (m Model) ActiveTab() tabKind { //nolint:gocritic
89+
return m.activeTab
90+
}
12491

125-
lst := list.New(tabItems, delegate, 0, 0)
126-
lst.KeyMap = listKeys
127-
lst.SetFilteringEnabled(true)
128-
// The visible tab strip is rendered in the view; a per-list Title
129-
// is redundant, so clear it to keep the tab bar the only label.
130-
lst.Title = ""
131-
lst.SetShowTitle(false)
132-
lst.Styles.Title = titleStyle
133-
lists[i] = lst
134-
}
92+
// ExitMessage returns the styled post-exit message the model set while
93+
// handling its final action (e.g., a successful copy that generated a
94+
// terragrunt.values.hcl file). The caller is responsible for printing it
95+
// after the tea.Program returns, once the alt screen has been torn down.
96+
func (m Model) ExitMessage() string { //nolint:gocritic
97+
return m.exitMessage
98+
}
13599

136-
vp := viewport.New(viewport.WithWidth(0), viewport.WithHeight(0))
100+
// Init implements bubbletea.Model.Init
101+
func (m Model) Init() tea.Cmd { //nolint:gocritic
102+
cmds := []tea.Cmd{m.buttonBar.Init()}
137103

138-
bs := make([]string, len(availableButtons))
139-
for i, b := range availableButtons {
140-
bs[i] = b.String()
104+
if m.componentCh != nil {
105+
cmds = append(cmds, m.listenForComponent())
141106
}
142107

143-
bb := buttonbar.New(bs)
144-
145-
return Model{
146-
lists: lists,
147-
listKeys: listKeys,
148-
delegateKeys: delegateKeys,
149-
viewport: vp,
150-
buttonBar: bb,
151-
pagerKeys: pagerKeys,
152-
terragruntOptions: opts,
153-
logger: l,
154-
componentCh: componentCh,
155-
}
108+
return tea.Batch(cmds...)
156109
}
157110

158-
// filterItemsByTab returns the subset of items whose Kind belongs in tab t.
159-
// TabAll returns everything unchanged.
160-
func filterItemsByTab(items []list.Item, t tabKind) []list.Item {
161-
if t == TabAll {
162-
return items
163-
}
164-
165-
out := make([]list.Item, 0, len(items))
166-
167-
for _, it := range items {
168-
entry, ok := it.(*ComponentEntry)
169-
if !ok {
170-
continue
171-
}
172-
173-
if t.matches(entry.Kind()) {
174-
out = append(out, entry)
175-
}
176-
}
111+
// List returns the currently active list — the one filtered by the active
112+
// tab. Exposed for tests and view code that need to inspect items.
113+
func (m Model) List() list.Model { //nolint:gocritic
114+
return m.lists[m.activeTab]
115+
}
177116

178-
return out
117+
func (b button) String() string {
118+
return []string{
119+
"Scaffold",
120+
"View Source in Browser",
121+
}[b]
179122
}
180123

181124
// insertComponentSorted inserts a component into every tab whose filter
@@ -246,6 +189,45 @@ func (m *Model) insertIntoList(idx int, entry *ComponentEntry) tea.Cmd {
246189
return cmd
247190
}
248191

192+
func (m Model) listenForComponent() tea.Cmd { //nolint:gocritic
193+
ch := m.componentCh
194+
if ch == nil {
195+
return nil
196+
}
197+
198+
return func() tea.Msg {
199+
c, ok := <-ch
200+
if !ok {
201+
return nil
202+
}
203+
204+
return componentMsg{entry: c}
205+
}
206+
}
207+
208+
// filterItemsByTab returns the subset of items whose Kind belongs in tab t.
209+
// TabAll returns everything unchanged.
210+
func filterItemsByTab(items []list.Item, t tabKind) []list.Item {
211+
if t == TabAll {
212+
return items
213+
}
214+
215+
out := make([]list.Item, 0, len(items))
216+
217+
for _, it := range items {
218+
entry, ok := it.(*ComponentEntry)
219+
if !ok {
220+
continue
221+
}
222+
223+
if t.matches(entry.Kind()) {
224+
out = append(out, entry)
225+
}
226+
}
227+
228+
return out
229+
}
230+
249231
// isDuplicate reports whether any item in the list has the same source path
250232
// as sourcePath. This uses the stable TerraformSourcePath identity rather
251233
// than the display title, so distinct components that share a title are not
@@ -262,29 +244,54 @@ func isDuplicate(items []list.Item, sourcePath string) bool {
262244
return false
263245
}
264246

265-
func (m Model) listenForComponent() tea.Cmd { //nolint:gocritic
266-
ch := m.componentCh
267-
if ch == nil {
268-
return nil
269-
}
247+
func newModelWithItems(l log.Logger, opts *options.TerragruntOptions, items []list.Item, componentCh chan *ComponentEntry) Model {
248+
listKeys := tui.NewListKeyMap()
249+
delegateKeys := tui.NewDelegateKeyMap()
250+
pagerKeys := tui.NewPagerKeyMap()
270251

271-
return func() tea.Msg {
272-
c, ok := <-ch
273-
if !ok {
274-
return nil
275-
}
252+
delegate := newCatalogDelegate(delegateKeys)
276253

277-
return componentMsg{entry: c}
254+
titleStyle := lipgloss.NewStyle().
255+
Foreground(lipgloss.Color(titleForegroundColor)).
256+
Background(lipgloss.Color(titleBackgroundColor)).
257+
Padding(0, 1)
258+
259+
var lists [numTabs]list.Model
260+
261+
for i := range int(numTabs) {
262+
t := tabKind(i)
263+
264+
tabItems := filterItemsByTab(items, t)
265+
266+
lst := list.New(tabItems, delegate, 0, 0)
267+
lst.KeyMap = listKeys
268+
lst.SetFilteringEnabled(true)
269+
// The visible tab strip is rendered in the view; a per-list Title
270+
// is redundant, so clear it to keep the tab bar the only label.
271+
lst.Title = ""
272+
lst.SetShowTitle(false)
273+
lst.Styles.Title = titleStyle
274+
lists[i] = lst
278275
}
279-
}
280276

281-
// Init implements bubbletea.Model.Init
282-
func (m Model) Init() tea.Cmd { //nolint:gocritic
283-
cmds := []tea.Cmd{m.buttonBar.Init()}
277+
vp := viewport.New(viewport.WithWidth(0), viewport.WithHeight(0))
284278

285-
if m.componentCh != nil {
286-
cmds = append(cmds, m.listenForComponent())
279+
bs := make([]string, len(availableButtons))
280+
for i, b := range availableButtons {
281+
bs[i] = b.String()
287282
}
288283

289-
return tea.Batch(cmds...)
284+
bb := buttonbar.New(bs)
285+
286+
return Model{
287+
lists: lists,
288+
listKeys: listKeys,
289+
delegateKeys: delegateKeys,
290+
viewport: vp,
291+
buttonBar: bb,
292+
pagerKeys: pagerKeys,
293+
terragruntOptions: opts,
294+
logger: l,
295+
componentCh: componentCh,
296+
}
290297
}

0 commit comments

Comments
 (0)