• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mindersec / minder / 14315603253

07 Apr 2025 05:28PM UTC coverage: 56.758% (-0.01%) from 56.772%
14315603253

push

github

web-flow
build(deps): bump golangci/golangci-lint-action from 6.5.2 to 7.0.0 (#5548)

* build(deps): bump golangci/golangci-lint-action from 6.5.2 to 7.0.0

Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 6.5.2 to 7.0.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](https://github.com/golangci/golangci-lint-action/compare/55c2c1448...148140484)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Migrate to golangci-lint version 2

* Fix newly-detected golangci-lint issues

* Fix remaining lint issues from new golangci-lint

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Evan Anderson <evan@stacklok.com>

53 of 164 new or added lines in 78 files covered. (32.32%)

2 existing lines in 1 file now uncovered.

18301 of 32244 relevant lines covered (56.76%)

36.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/internal/util/cli/multi_select.go
1
// SPDX-FileCopyrightText: Copyright 2023 The Minder Authors
2
// SPDX-License-Identifier: Apache-2.0
3

4
package cli
5

6
import (
7
        "cmp"
8
        "fmt"
9
        "io"
10
        "slices"
11
        "strings"
12

13
        "github.com/charmbracelet/bubbles/key"
14
        "github.com/charmbracelet/bubbles/list"
15
        tea "github.com/charmbracelet/bubbletea"
16
        "github.com/charmbracelet/lipgloss"
17
)
18

19
// MultiSelect implements the necessary logic to implement an
20
// interactive multi-select menu for the CLI.
21
//
22
// Given a list of string as choices, returns those interactively
23
// selected by the user.
24
func MultiSelect(choices []string) ([]string, error) {
×
25
        items := make([]list.Item, 0, len(choices))
×
26
        for _, c := range choices {
×
27
                items = append(items, item{title: c})
×
28
        }
×
29

30
        slices.SortFunc(items, func(a, b list.Item) int {
×
31
                return cmp.Compare(a.(item).title, b.(item).title)
×
32
        })
×
33

34
        l := list.New(items, itemDelegate{}, 0, 0)
×
35
        l.Title = "Select repos to register"
×
36
        l.Styles.Title = Header
×
37
        l.AdditionalShortHelpKeys = extraKeys
×
38
        l.AdditionalFullHelpKeys = extraKeys
×
39

×
40
        height := 30 // 20 + 10, 10 is a magic number to show 20 items
×
41
        if size := len(items); size < 20 {
×
42
                height = size + 10
×
43
        }
×
44
        model := model{list: l, height: height}
×
45
        p := tea.NewProgram(model)
×
46
        if _, err := p.Run(); err != nil {
×
47
                return nil, err
×
48
        }
×
49

50
        selection := make([]string, 0, len(items))
×
51
        for _, listItem := range items {
×
52
                item := listItem.(item)
×
53
                if item.checked {
×
54
                        selection = append(selection, item.title)
×
55
                }
×
56
        }
57

58
        return selection, nil
×
59
}
60

61
var (
62
        itemStyle         = lipgloss.NewStyle().PaddingLeft(4)
63
        selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(SecondaryColor)
64
)
65

66
// item represents the model object for every item in the multi-select
67
// list.
68
type item struct {
69
        title   string
70
        checked bool
71
}
72

73
func (i item) Title() string       { return i.title }
×
NEW
74
func (item) Description() string   { return "" }
×
75
func (i item) FilterValue() string { return i.title }
×
76

77
// itemDelegate packs all the logic related to rendering items in TUI
78
type itemDelegate struct{}
79

NEW
80
func (itemDelegate) Height() int                             { return 1 }
×
NEW
81
func (itemDelegate) Spacing() int                            { return 0 }
×
NEW
82
func (itemDelegate) Update(_ tea.Msg, _ *list.Model) tea.Cmd { return nil }
×
NEW
83
func (itemDelegate) Render(w io.Writer, m list.Model, index int, listItem list.Item) {
×
84
        i, ok := listItem.(item)
×
85
        if !ok {
×
86
                return
×
87
        }
×
88

89
        fn := itemStyle.Render
×
90
        if index == m.Index() {
×
91
                fn = func(s ...string) string {
×
92
                        return selectedItemStyle.Render("> " + strings.Join(s, " "))
×
93
                }
×
94
        }
95

96
        checked := "[ ]"
×
97
        if i.checked {
×
98
                checked = "[x]"
×
99
        }
×
100

101
        fmt.Fprint(w, fn(checked, i.title))
×
102
}
103

104
// model represents the actual multi-select, with all its rendering,
105
// navigation, and selection logic.
106
type model struct {
107
        list   list.Model
108
        height int
109
}
110

NEW
111
func (model) Init() tea.Cmd {
×
112
        return nil
×
113
}
×
114

115
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
×
116
        switch msg := msg.(type) {
×
117
        case tea.WindowSizeMsg:
×
118
                m.list.SetSize(0, m.height)
×
119

120
        case tea.KeyMsg:
×
121
                switch msg.String() {
×
122
                case "ctrl+c", "enter":
×
123
                        return m, tea.Quit
×
124
                case " ":
×
125
                        idx := m.list.Index()
×
126
                        oldItem := m.list.SelectedItem().(item)
×
127
                        cmd := m.list.SetItem(idx, item{
×
128
                                title:   oldItem.title,
×
129
                                checked: !oldItem.checked,
×
130
                        })
×
131
                        return m, cmd
×
132
                }
133
        }
134

135
        var cmd tea.Cmd
×
136
        m.list, cmd = m.list.Update(msg)
×
137
        return m, cmd
×
138
}
139

140
func (m model) View() string {
×
141
        return m.list.View()
×
142
}
×
143

144
func extraKeys() []key.Binding {
×
145
        return []key.Binding{
×
146
                key.NewBinding(
×
147
                        key.WithKeys("space"),
×
148
                        key.WithHelp("space", "select item"),
×
149
                ),
×
150
        }
×
151
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc