101 lines
2 KiB
Go
101 lines
2 KiB
Go
package cli
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"net/url"
|
|
"os"
|
|
"strings"
|
|
|
|
"golang.org/x/term"
|
|
)
|
|
|
|
type Candidate struct {
|
|
Value string
|
|
Source string
|
|
}
|
|
|
|
func ResolveProfileName(flagProfile, envProfile, currentProfile string) string {
|
|
for _, candidate := range []string{flagProfile, envProfile, currentProfile} {
|
|
if value := strings.TrimSpace(candidate); value != "" {
|
|
return value
|
|
}
|
|
}
|
|
|
|
return "default"
|
|
}
|
|
|
|
func FirstNonEmpty(candidates ...Candidate) (string, string) {
|
|
for _, candidate := range candidates {
|
|
if value := strings.TrimSpace(candidate.Value); value != "" {
|
|
return value, candidate.Source
|
|
}
|
|
}
|
|
|
|
return "", ""
|
|
}
|
|
|
|
func ValidateBaseURL(raw string) error {
|
|
parsed, err := url.Parse(raw)
|
|
if err != nil {
|
|
return fmt.Errorf("parse URL: %w", err)
|
|
}
|
|
if parsed.Scheme == "" || parsed.Host == "" {
|
|
return fmt.Errorf("must include scheme and host")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func PromptLine(reader *bufio.Reader, w io.Writer, label, defaultValue string) (string, error) {
|
|
if defaultValue != "" {
|
|
fmt.Fprintf(w, "%s [%s]: ", label, defaultValue)
|
|
} else {
|
|
fmt.Fprintf(w, "%s: ", label)
|
|
}
|
|
|
|
line, err := reader.ReadString('\n')
|
|
if err != nil && err != io.EOF {
|
|
return "", err
|
|
}
|
|
|
|
line = strings.TrimSpace(line)
|
|
if line == "" {
|
|
return defaultValue, nil
|
|
}
|
|
return line, nil
|
|
}
|
|
|
|
func PromptSecret(stdin *os.File, w io.Writer, label string, hasStoredSecret bool, storedSecret string) (string, error) {
|
|
if hasStoredSecret {
|
|
fmt.Fprintf(w, "%s [stored, leave blank to keep]: ", label)
|
|
} else {
|
|
fmt.Fprintf(w, "%s: ", label)
|
|
}
|
|
|
|
if term.IsTerminal(int(stdin.Fd())) {
|
|
secret, err := term.ReadPassword(int(stdin.Fd()))
|
|
fmt.Fprintln(w)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
value := strings.TrimSpace(string(secret))
|
|
if value == "" && hasStoredSecret {
|
|
return storedSecret, nil
|
|
}
|
|
return value, nil
|
|
}
|
|
|
|
reader := bufio.NewReader(stdin)
|
|
line, err := reader.ReadString('\n')
|
|
if err != nil && err != io.EOF {
|
|
return "", err
|
|
}
|
|
|
|
value := strings.TrimSpace(line)
|
|
if value == "" && hasStoredSecret {
|
|
return storedSecret, nil
|
|
}
|
|
return value, nil
|
|
}
|