96 lines
2.9 KiB
Go
96 lines
2.9 KiB
Go
package app
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
func isCLIFlagToken(arg string) bool {
|
|
return strings.HasPrefix(arg, "-") && arg != "-"
|
|
}
|
|
|
|
func pullLeadingSessionID(args []string) (string, []string) {
|
|
if len(args) == 0 || isCLIFlagToken(args[0]) {
|
|
return "", args
|
|
}
|
|
rest := append([]string(nil), args[1:]...)
|
|
return strings.TrimSpace(args[0]), rest
|
|
}
|
|
|
|
func applyPositionalSessionID(command, positional string, sessionID *string) error {
|
|
positional = strings.TrimSpace(positional)
|
|
if positional == "" {
|
|
return nil
|
|
}
|
|
existing := strings.TrimSpace(*sessionID)
|
|
if existing != "" && existing != positional {
|
|
return fmt.Errorf("%s: positional session id %q does not match expected session id %q", command, positional, existing)
|
|
}
|
|
*sessionID = positional
|
|
return nil
|
|
}
|
|
|
|
func applyParsedSessionIDArg(command string, fs *flag.FlagSet, sessionID *string) error {
|
|
switch fs.NArg() {
|
|
case 0:
|
|
return nil
|
|
case 1:
|
|
return applyPositionalSessionID(command, fs.Arg(0), sessionID)
|
|
default:
|
|
return fmt.Errorf("%s: unexpected positional arguments", command)
|
|
}
|
|
}
|
|
|
|
func resolveParsedSessionID(command, positionalSessionID string, fs *flag.FlagSet, sessionID *string) error {
|
|
if strings.TrimSpace(positionalSessionID) == "" {
|
|
return applyParsedSessionIDArg(command, fs, sessionID)
|
|
}
|
|
if fs.NArg() != 0 {
|
|
return fmt.Errorf("%s: unexpected positional arguments", command)
|
|
}
|
|
return applyPositionalSessionID(command, positionalSessionID, sessionID)
|
|
}
|
|
|
|
func parseSessionAwareFlags(command string, fs *flag.FlagSet, args []string, sessionID *string) error {
|
|
positionalSessionID, args := pullLeadingSessionID(args)
|
|
if err := fs.Parse(args); err != nil {
|
|
return fmt.Errorf("%s: invalid flags: %w", command, err)
|
|
}
|
|
return resolveParsedSessionID(command, positionalSessionID, fs, sessionID)
|
|
}
|
|
|
|
func parseSessionIDAndOnePositionalArg(command, argName string, fs *flag.FlagSet, args []string, sessionID *string) (string, error) {
|
|
var positionalSessionID string
|
|
value := ""
|
|
if len(args) >= 2 && !isCLIFlagToken(args[0]) && !isCLIFlagToken(args[1]) {
|
|
positionalSessionID = strings.TrimSpace(args[0])
|
|
value = strings.TrimSpace(args[1])
|
|
args = append([]string(nil), args[2:]...)
|
|
}
|
|
|
|
if err := fs.Parse(args); err != nil {
|
|
return "", fmt.Errorf("%s: invalid flags: %w", command, err)
|
|
}
|
|
if value == "" {
|
|
switch fs.NArg() {
|
|
case 2:
|
|
positionalSessionID = strings.TrimSpace(fs.Arg(0))
|
|
value = strings.TrimSpace(fs.Arg(1))
|
|
case 1:
|
|
if strings.TrimSpace(*sessionID) == "" {
|
|
return "", fmt.Errorf("%s: expected session_id and %s", command, argName)
|
|
}
|
|
value = strings.TrimSpace(fs.Arg(0))
|
|
default:
|
|
return "", fmt.Errorf("%s: expected session_id and %s", command, argName)
|
|
}
|
|
} else if fs.NArg() != 0 {
|
|
return "", fmt.Errorf("%s: unexpected positional arguments", command)
|
|
}
|
|
if err := applyPositionalSessionID(command, positionalSessionID, sessionID); err != nil {
|
|
return "", err
|
|
}
|
|
return value, nil
|
|
}
|