mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-09-18 06:22:17 +00:00
Fix cli version comparison and improve setup command (#3518)
This commit is contained in:
@@ -13,8 +13,10 @@ import (
|
||||
|
||||
// Command exports the setup command.
|
||||
var Command = &cli.Command{
|
||||
Name: "setup",
|
||||
Usage: "setup the woodpecker-cli for the first time",
|
||||
Name: "setup",
|
||||
Usage: "setup the woodpecker-cli for the first time",
|
||||
Args: true,
|
||||
ArgsUsage: "[server-url]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "server-url",
|
||||
@@ -45,6 +47,9 @@ func setup(c *cli.Context) error {
|
||||
}
|
||||
|
||||
serverURL := c.String("server-url")
|
||||
if serverURL == "" {
|
||||
serverURL = c.Args().First()
|
||||
}
|
||||
|
||||
if serverURL == "" {
|
||||
serverURL, err = ui.Ask("Enter the URL of the woodpecker server", "https://ci.woodpecker-ci.org", true)
|
||||
|
@@ -10,6 +10,7 @@ import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/charmbracelet/huh/spinner"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
@@ -37,13 +38,27 @@ func receiveTokenFromUI(c context.Context, serverURL string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
spinnerCtx, spinnerDone := context.WithCancelCause(c)
|
||||
go func() {
|
||||
err = spinner.New().
|
||||
Title("Waiting for token ...").
|
||||
Context(spinnerCtx).
|
||||
Run()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
// wait for token to be received or timeout
|
||||
select {
|
||||
case token := <-tokenReceived:
|
||||
spinnerDone(nil)
|
||||
return token, nil
|
||||
case <-c.Done():
|
||||
spinnerDone(nil)
|
||||
return "", c.Err()
|
||||
case <-time.After(5 * time.Minute):
|
||||
spinnerDone(nil)
|
||||
return "", errors.New("timed out waiting for token")
|
||||
}
|
||||
}
|
||||
|
@@ -1,79 +1,26 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/huh"
|
||||
)
|
||||
|
||||
type askModel struct {
|
||||
prompt string
|
||||
required bool
|
||||
textInput textinput.Model
|
||||
err error
|
||||
}
|
||||
|
||||
func (m askModel) Init() tea.Cmd {
|
||||
return textinput.Blink
|
||||
}
|
||||
|
||||
func (m askModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
var cmd tea.Cmd
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case tea.KeyMsg:
|
||||
switch msg.Type {
|
||||
case tea.KeyEnter:
|
||||
if !m.required || (m.required && strings.TrimSpace(m.textInput.Value()) != "") {
|
||||
return m, tea.Quit
|
||||
}
|
||||
case tea.KeyCtrlC, tea.KeyEsc:
|
||||
return m, tea.Quit
|
||||
}
|
||||
default:
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
m.textInput, cmd = m.textInput.Update(msg)
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
func (m askModel) View() string {
|
||||
return fmt.Sprintf(
|
||||
"%s\n\n%s\n\n%s",
|
||||
m.prompt,
|
||||
m.textInput.View(),
|
||||
"(esc to quit)",
|
||||
) + "\n"
|
||||
}
|
||||
|
||||
func Ask(prompt, placeholder string, required bool) (string, error) {
|
||||
ti := textinput.New()
|
||||
ti.Placeholder = placeholder
|
||||
ti.Focus()
|
||||
ti.CharLimit = 156
|
||||
ti.Width = 40
|
||||
|
||||
p := tea.NewProgram(askModel{
|
||||
prompt: prompt,
|
||||
textInput: ti,
|
||||
required: required,
|
||||
err: nil,
|
||||
})
|
||||
|
||||
_m, err := p.Run()
|
||||
var input string
|
||||
err := huh.NewInput().
|
||||
Title(prompt).
|
||||
Value(&input).
|
||||
Placeholder(placeholder).Validate(func(s string) error {
|
||||
if required && strings.TrimSpace(s) == "" {
|
||||
return errors.New("required")
|
||||
}
|
||||
return nil
|
||||
}).Run()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
m, ok := _m.(askModel)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("unexpected model: %T", _m)
|
||||
}
|
||||
|
||||
text := strings.TrimSpace(m.textInput.Value())
|
||||
|
||||
return text, nil
|
||||
return strings.TrimSpace(input), nil
|
||||
}
|
||||
|
@@ -1,71 +1,19 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/huh"
|
||||
)
|
||||
|
||||
type confirmModel struct {
|
||||
confirmed bool
|
||||
prompt string
|
||||
err error
|
||||
}
|
||||
|
||||
func (m confirmModel) Init() tea.Cmd {
|
||||
return textinput.Blink
|
||||
}
|
||||
|
||||
func (m confirmModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
var cmd tea.Cmd
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case tea.KeyMsg:
|
||||
if msg.Runes != nil {
|
||||
switch msg.Runes[0] {
|
||||
case 'y':
|
||||
m.confirmed = true
|
||||
return m, tea.Quit
|
||||
case 'n':
|
||||
m.confirmed = false
|
||||
return m, tea.Quit
|
||||
}
|
||||
}
|
||||
|
||||
switch msg.Type {
|
||||
case tea.KeyCtrlC, tea.KeyEsc:
|
||||
return m, tea.Quit
|
||||
}
|
||||
default:
|
||||
return m, nil
|
||||
}
|
||||
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
func (m confirmModel) View() string {
|
||||
return fmt.Sprintf(
|
||||
"%s y / n (esc to quit)",
|
||||
m.prompt,
|
||||
) + "\n"
|
||||
}
|
||||
|
||||
func Confirm(prompt string) (bool, error) {
|
||||
p := tea.NewProgram(confirmModel{
|
||||
prompt: prompt,
|
||||
err: nil,
|
||||
})
|
||||
|
||||
_m, err := p.Run()
|
||||
var confirm bool
|
||||
err := huh.NewConfirm().
|
||||
Title(prompt).
|
||||
Affirmative("Yes!").
|
||||
Negative("No.").
|
||||
Value(&confirm).Run()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
m, ok := _m.(confirmModel)
|
||||
if !ok {
|
||||
return false, fmt.Errorf("unexpected model: %T", _m)
|
||||
}
|
||||
|
||||
return m.confirmed, nil
|
||||
return confirm, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user