Skip to content
This repository was archived by the owner on Mar 24, 2025. It is now read-only.
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
117 changes: 117 additions & 0 deletions cmd/common/prompt.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package common

import (
"errors"
"html/template"
"strings"

"github.com/erikgeiser/promptkit/selection"
"github.com/erikgeiser/promptkit/textinput"
"github.com/jedib0t/go-pretty/v6/text"
"github.com/lithammer/fuzzysearch/fuzzy"
"github.com/rigdev/rig/pkg/utils"
"golang.org/x/exp/slices"
)

type GetInputOption = func(*textinput.TextInput)

// TODO What about non-string Selection
type SelectInputOption = func(s *selection.Selection[string])

var ValidateAllOpt = func(inp *textinput.TextInput) {
Expand Down Expand Up @@ -73,6 +80,24 @@ var SelectEnableFilterOpt = func(s *selection.Selection[string]) {
s.Filter = selection.FilterContainsCaseSensitive[string]
}

var SelectFuzzyFilterOpt = func(s *selection.Selection[string]) {
s.Filter = func(filter string, choice *selection.Choice[string]) bool {
return fuzzy.Match(filter, choice.Value)
}
}

var SelectExtendTemplateOpt = func(t template.FuncMap) SelectInputOption {
return func(s *selection.Selection[string]) {
s.ExtendedTemplateFuncs = t
}
}

var SelectTemplateOpt = func(template string) SelectInputOption {
return func(s *selection.Selection[string]) {
s.Template = template
}
}

func PromptInput(label string, opts ...GetInputOption) (string, error) {
input := textinput.New(label)
for _, opt := range opts {
Expand Down Expand Up @@ -147,3 +172,95 @@ var (
{{- end -}}
`
)

func PromptTableSelect(label string, choices [][]string, columnHeaders []string, opts ...SelectInputOption) (int, error) {
// TODO Honestly, this thing with manually creating the table rows and header
// feels like I'm reinventing the wheel. Maybe find some package to do this for me?
// I can't just use our table pretty printer as I don't want to print a table,
// I want a string for each individual row and a couple strings for the table headder
rows, colLengths, err := formatRows(choices, " | ")
if err != nil {
return 0, err
}

if len(colLengths) != len(columnHeaders) {
return 0, errors.New("number of columns in 'choices' and 'columnHeaders' don't agree")
}

var header string
for idx, c := range columnHeaders {
header += text.AlignCenter.Apply(c, colLengths[idx])
}
headerBorder := strings.Repeat("-", len(header))

opts = append(opts, SelectExtendTemplateOpt(map[string]any{
"header": func() string { return header },
"headerBorder": func() string { return headerBorder },
}))
idx, _, err := PromptSelect(label, rows, opts...)
return idx, err
}

var tableSelectTemplate = `
{{- if .Prompt -}}
{{ Bold .Prompt }}
{{ end -}}
{{ if .IsFiltered }}
{{- print .FilterPrompt " " .FilterInput }}
{{ end }}
{{ print " " header }}
{{ println " " headerBorder }}
{{- range $i, $choice := .Choices }}
{{- if IsScrollUpHintPosition $i }}
{{- "⇡ " -}}
{{- else if IsScrollDownHintPosition $i -}}
{{- "⇣ " -}}
{{- else -}}
{{- " " -}}
{{- end -}}

{{- if eq $.SelectedIndex $i }}
{{- print (Foreground "32" (Bold "▸ ")) (Selected $choice) "\n" }}
{{- else }}
{{- print " " (Unselected $choice) "\n" }}
{{- end }}
{{- end}}`

func formatRows(rows [][]string, colDelimiter string) ([]string, []int, error) {
if len(rows) == 0 {
return nil, nil, nil
}

for _, r := range rows[1:] {
if len(r) != len(rows[0]) {
return nil, nil, errors.New("the rows are not all of equal length")
}
}

var colLengths []int
for cIdx := range rows[0] {
longest := 0
for _, row := range rows {
l := len(row[cIdx])
if l > longest {
longest = l
}
}
colLengths = append(colLengths, longest)
}

var result []string
for _, row := range rows {
var s string
for cIdx, c := range row {
s += text.AlignLeft.Apply(c, colLengths[cIdx]) + colDelimiter
}
result = append(result, s)
}

for idx := range colLengths {
colLengths[idx] += len(colDelimiter)
}

return result, colLengths, nil
}
2 changes: 1 addition & 1 deletion cmd/rig-admin/cmd/capsule.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func CapsuleCreateBuild(ctx context.Context, cmd *cobra.Command, args []string,
return err
}

logger.Info("build created", zap.String("build_id", buildID))
logger.Info("build created", zap.String("build_id", buildID.BuildID))

return nil
}
Expand Down
Loading