mirror of
https://github.com/strongdm/comply
synced 2024-09-15 09:14:37 +00:00
69 lines
1.8 KiB
Go
69 lines
1.8 KiB
Go
|
package goptions
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
"regexp"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
_LONG_FLAG_REGEXP = `--[[:word:]-]+`
|
||
|
_SHORT_FLAG_REGEXP = `-[[:alnum:]]`
|
||
|
_QUOTED_STRING_REGEXP = `'((?:\\'|[^\\'])+)'`
|
||
|
_OPTION_REGEXP = `([[:word:]-]+)(?:=` + _QUOTED_STRING_REGEXP + `)?`
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
optionRegexp = regexp.MustCompile(`^(` + strings.Join([]string{_SHORT_FLAG_REGEXP, _LONG_FLAG_REGEXP, _OPTION_REGEXP}, "|") + `)(?:,|$)`)
|
||
|
)
|
||
|
|
||
|
func parseStructField(fieldValue reflect.Value, tag string) (*Flag, error) {
|
||
|
f := &Flag{
|
||
|
value: fieldValue,
|
||
|
DefaultValue: fieldValue.Interface(),
|
||
|
optionMeta: make(map[string]interface{}),
|
||
|
}
|
||
|
for {
|
||
|
tag = strings.TrimSpace(tag)
|
||
|
if len(tag) == 0 {
|
||
|
break
|
||
|
}
|
||
|
idx := optionRegexp.FindStringSubmatchIndex(tag)
|
||
|
if idx == nil {
|
||
|
return nil, fmt.Errorf("Could not find a valid flag definition at the beginning of \"%s\"", tag)
|
||
|
}
|
||
|
option := tag[idx[2]:idx[3]]
|
||
|
|
||
|
if strings.HasPrefix(option, "--") {
|
||
|
if f.Long != "" {
|
||
|
return nil, fmt.Errorf("Multiple flags assigned to a member: %s", strings.Join([]string{"--" + f.Long, option}, ", "))
|
||
|
}
|
||
|
f.Long = option[2:]
|
||
|
} else if strings.HasPrefix(option, "-") {
|
||
|
if f.Short != "" {
|
||
|
return nil, fmt.Errorf("Multiple flags assigned to a member: %s", strings.Join([]string{"-" + f.Short, option}, ", "))
|
||
|
}
|
||
|
f.Short = option[1:]
|
||
|
} else {
|
||
|
option := tag[idx[4]:idx[5]]
|
||
|
value := ""
|
||
|
if idx[6] != -1 {
|
||
|
value = tag[idx[6]:idx[7]]
|
||
|
}
|
||
|
optionmap := optionMapForType(fieldValue.Type())
|
||
|
opf, ok := optionmap[option]
|
||
|
if !ok {
|
||
|
return nil, fmt.Errorf("Unknown option %s", option)
|
||
|
}
|
||
|
err := opf(f, option, value)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("Option %s invalid: %s", option, err)
|
||
|
}
|
||
|
}
|
||
|
// Keep remainder
|
||
|
tag = tag[idx[1]:]
|
||
|
}
|
||
|
return f, nil
|
||
|
}
|