Option types: bool int, int-array, string, string-array, string-map, file, dir
148 lines
3.5 KiB
Go
148 lines
3.5 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"slices"
|
|
"strings"
|
|
)
|
|
|
|
type cliOptionBase struct {
|
|
name string
|
|
shortAlias string
|
|
aliases []string
|
|
description string
|
|
isArray bool
|
|
hidden bool
|
|
specialValues map[string]SpecialValueFunc
|
|
incompatibleWith []string
|
|
}
|
|
|
|
func (opt *cliOptionBase) getBase() *cliOptionBase {
|
|
return opt
|
|
}
|
|
|
|
func (opt *cliOptionBase) getTargetVar() (any, string) {
|
|
return nil, "n/a"
|
|
}
|
|
|
|
func (opt *cliOptionBase) Is(name string) (result bool) {
|
|
if result = opt.name == name; !result && len(opt.aliases) > 0 {
|
|
result = slices.Contains(opt.aliases, name)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (opt *cliOptionBase) isHidden() bool {
|
|
return opt.hidden
|
|
}
|
|
|
|
func (opt *cliOptionBase) SetHidden(hidden bool) {
|
|
opt.hidden = hidden
|
|
}
|
|
|
|
func (opt *cliOptionBase) AddSpecialValue(cliValue string, specialFunc SpecialValueFunc) {
|
|
if opt.specialValues == nil {
|
|
opt.specialValues = make(map[string]SpecialValueFunc)
|
|
}
|
|
opt.specialValues[cliValue] = specialFunc
|
|
}
|
|
|
|
func (opt *cliOptionBase) getSpecialFunc(cliValue string) (specialFunc SpecialValueFunc, exists bool) {
|
|
if len(opt.specialValues) > 0 {
|
|
specialFunc, exists = opt.specialValues[cliValue]
|
|
}
|
|
return
|
|
}
|
|
|
|
func (opt *cliOptionBase) isSet() bool {
|
|
return false
|
|
}
|
|
|
|
func (opt *cliOptionBase) requiresValue() bool {
|
|
return true
|
|
}
|
|
|
|
func (opt *cliOptionBase) addIncompatibleOption(names ...string) {
|
|
opt.incompatibleWith = append(opt.incompatibleWith, names...)
|
|
}
|
|
|
|
func (opt *cliOptionBase) parse(parser cliParser, valuePtr *string) (err error) {
|
|
return fmt.Errorf("unhandled option %q", opt.name)
|
|
}
|
|
|
|
func (opt *cliOptionBase) getDefaultValue() string {
|
|
return ""
|
|
}
|
|
|
|
func pluralSuffix(word string) (suffix string) {
|
|
if len(word) > 0 {
|
|
if strings.HasSuffix(word, "x") || strings.HasSuffix(word, "s") || strings.HasSuffix(word, "ch") {
|
|
suffix = "es"
|
|
} else {
|
|
suffix = "s"
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func makePlural(word string) (plural string) {
|
|
return word + pluralSuffix(word)
|
|
}
|
|
|
|
func (opt *cliOptionBase) makeOptTemplate(isArray bool, valueType string) (templ string) {
|
|
var suffix, multiValue string
|
|
if isArray {
|
|
suffix = "(" + pluralSuffix(opt.name) + ")"
|
|
multiValue = `["," ...]`
|
|
}
|
|
if opt.shortAlias != "" {
|
|
templ = fmt.Sprintf(`-%s, --%s%s <%s>%s`, opt.shortAlias, opt.name, suffix, valueType, multiValue)
|
|
} else {
|
|
templ = fmt.Sprintf(`--%s%s <%s>%s`, opt.name, suffix, valueType, multiValue)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (opt *cliOptionBase) makeOptSimpleTemplate(valueRequired, multiValue bool, valueType string) (templ string) {
|
|
var valueSpec, dots string
|
|
|
|
if multiValue {
|
|
dots = " ..."
|
|
}
|
|
if len(valueType) > 0 {
|
|
valueSpec = " <" + valueType + ">" + dots
|
|
if !valueRequired {
|
|
valueSpec = " [" + valueSpec[1:] + "]"
|
|
}
|
|
}
|
|
|
|
if opt.shortAlias != "" {
|
|
templ = fmt.Sprintf(`-%s, --%s%s`, opt.shortAlias, opt.name, valueSpec)
|
|
} else {
|
|
templ = fmt.Sprintf(`--%s%s`, opt.name, valueSpec)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (opt *cliOptionBase) getSpecialValue(parser cliParser, value string, targetVar any) (boxedValue any, err error) {
|
|
if specialFunc, exists := opt.getSpecialFunc(value); exists {
|
|
manager := parser.(OptManager)
|
|
boxedValue, err = specialFunc(manager, value, targetVar)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (opt *cliOptionBase) fetchOptionValue(parser cliParser, argIndex int, valuePtr *string) (value string, skipNextArg bool, err error) {
|
|
if valuePtr != nil {
|
|
value = *valuePtr
|
|
} else {
|
|
if source, optionPresent := parser.getOptionValue(argIndex); optionPresent {
|
|
skipNextArg = true
|
|
value = source
|
|
} else {
|
|
err = errMissingOptionValue(opt.name)
|
|
}
|
|
}
|
|
return
|
|
}
|