Use vendored go-swagger (#8087)
* Use vendored go-swagger * vendor go-swagger * revert un wanteed change * remove un-needed GO111MODULE * Update Makefile Co-Authored-By: techknowlogick <matti@mdranta.net>
This commit is contained in:
parent
4cb1bdddc8
commit
9fe4437bda
686 changed files with 143379 additions and 17 deletions
597
vendor/github.com/jessevdk/go-flags/ini.go
generated
vendored
Normal file
597
vendor/github.com/jessevdk/go-flags/ini.go
generated
vendored
Normal file
|
@ -0,0 +1,597 @@
|
|||
package flags
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IniError contains location information on where an error occurred.
|
||||
type IniError struct {
|
||||
// The error message.
|
||||
Message string
|
||||
|
||||
// The filename of the file in which the error occurred.
|
||||
File string
|
||||
|
||||
// The line number at which the error occurred.
|
||||
LineNumber uint
|
||||
}
|
||||
|
||||
// Error provides a "file:line: message" formatted message of the ini error.
|
||||
func (x *IniError) Error() string {
|
||||
return fmt.Sprintf(
|
||||
"%s:%d: %s",
|
||||
x.File,
|
||||
x.LineNumber,
|
||||
x.Message,
|
||||
)
|
||||
}
|
||||
|
||||
// IniOptions for writing
|
||||
type IniOptions uint
|
||||
|
||||
const (
|
||||
// IniNone indicates no options.
|
||||
IniNone IniOptions = 0
|
||||
|
||||
// IniIncludeDefaults indicates that default values should be written.
|
||||
IniIncludeDefaults = 1 << iota
|
||||
|
||||
// IniCommentDefaults indicates that if IniIncludeDefaults is used
|
||||
// options with default values are written but commented out.
|
||||
IniCommentDefaults
|
||||
|
||||
// IniIncludeComments indicates that comments containing the description
|
||||
// of an option should be written.
|
||||
IniIncludeComments
|
||||
|
||||
// IniDefault provides a default set of options.
|
||||
IniDefault = IniIncludeComments
|
||||
)
|
||||
|
||||
// IniParser is a utility to read and write flags options from and to ini
|
||||
// formatted strings.
|
||||
type IniParser struct {
|
||||
ParseAsDefaults bool // override default flags
|
||||
|
||||
parser *Parser
|
||||
}
|
||||
|
||||
type iniValue struct {
|
||||
Name string
|
||||
Value string
|
||||
Quoted bool
|
||||
LineNumber uint
|
||||
}
|
||||
|
||||
type iniSection []iniValue
|
||||
|
||||
type ini struct {
|
||||
File string
|
||||
Sections map[string]iniSection
|
||||
}
|
||||
|
||||
// NewIniParser creates a new ini parser for a given Parser.
|
||||
func NewIniParser(p *Parser) *IniParser {
|
||||
return &IniParser{
|
||||
parser: p,
|
||||
}
|
||||
}
|
||||
|
||||
// IniParse is a convenience function to parse command line options with default
|
||||
// settings from an ini formatted file. The provided data is a pointer to a struct
|
||||
// representing the default option group (named "Application Options"). For
|
||||
// more control, use flags.NewParser.
|
||||
func IniParse(filename string, data interface{}) error {
|
||||
p := NewParser(data, Default)
|
||||
|
||||
return NewIniParser(p).ParseFile(filename)
|
||||
}
|
||||
|
||||
// ParseFile parses flags from an ini formatted file. See Parse for more
|
||||
// information on the ini file format. The returned errors can be of the type
|
||||
// flags.Error or flags.IniError.
|
||||
func (i *IniParser) ParseFile(filename string) error {
|
||||
ini, err := readIniFromFile(filename)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return i.parse(ini)
|
||||
}
|
||||
|
||||
// Parse parses flags from an ini format. You can use ParseFile as a
|
||||
// convenience function to parse from a filename instead of a general
|
||||
// io.Reader.
|
||||
//
|
||||
// The format of the ini file is as follows:
|
||||
//
|
||||
// [Option group name]
|
||||
// option = value
|
||||
//
|
||||
// Each section in the ini file represents an option group or command in the
|
||||
// flags parser. The default flags parser option group (i.e. when using
|
||||
// flags.Parse) is named 'Application Options'. The ini option name is matched
|
||||
// in the following order:
|
||||
//
|
||||
// 1. Compared to the ini-name tag on the option struct field (if present)
|
||||
// 2. Compared to the struct field name
|
||||
// 3. Compared to the option long name (if present)
|
||||
// 4. Compared to the option short name (if present)
|
||||
//
|
||||
// Sections for nested groups and commands can be addressed using a dot `.'
|
||||
// namespacing notation (i.e [subcommand.Options]). Group section names are
|
||||
// matched case insensitive.
|
||||
//
|
||||
// The returned errors can be of the type flags.Error or flags.IniError.
|
||||
func (i *IniParser) Parse(reader io.Reader) error {
|
||||
ini, err := readIni(reader, "")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return i.parse(ini)
|
||||
}
|
||||
|
||||
// WriteFile writes the flags as ini format into a file. See Write
|
||||
// for more information. The returned error occurs when the specified file
|
||||
// could not be opened for writing.
|
||||
func (i *IniParser) WriteFile(filename string, options IniOptions) error {
|
||||
return writeIniToFile(i, filename, options)
|
||||
}
|
||||
|
||||
// Write writes the current values of all the flags to an ini format.
|
||||
// See Parse for more information on the ini file format. You typically
|
||||
// call this only after settings have been parsed since the default values of each
|
||||
// option are stored just before parsing the flags (this is only relevant when
|
||||
// IniIncludeDefaults is _not_ set in options).
|
||||
func (i *IniParser) Write(writer io.Writer, options IniOptions) {
|
||||
writeIni(i, writer, options)
|
||||
}
|
||||
|
||||
func readFullLine(reader *bufio.Reader) (string, error) {
|
||||
var line []byte
|
||||
|
||||
for {
|
||||
l, more, err := reader.ReadLine()
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if line == nil && !more {
|
||||
return string(l), nil
|
||||
}
|
||||
|
||||
line = append(line, l...)
|
||||
|
||||
if !more {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return string(line), nil
|
||||
}
|
||||
|
||||
func optionIniName(option *Option) string {
|
||||
name := option.tag.Get("_read-ini-name")
|
||||
|
||||
if len(name) != 0 {
|
||||
return name
|
||||
}
|
||||
|
||||
name = option.tag.Get("ini-name")
|
||||
|
||||
if len(name) != 0 {
|
||||
return name
|
||||
}
|
||||
|
||||
return option.field.Name
|
||||
}
|
||||
|
||||
func writeGroupIni(cmd *Command, group *Group, namespace string, writer io.Writer, options IniOptions) {
|
||||
var sname string
|
||||
|
||||
if len(namespace) != 0 {
|
||||
sname = namespace
|
||||
}
|
||||
|
||||
if cmd.Group != group && len(group.ShortDescription) != 0 {
|
||||
if len(sname) != 0 {
|
||||
sname += "."
|
||||
}
|
||||
|
||||
sname += group.ShortDescription
|
||||
}
|
||||
|
||||
sectionwritten := false
|
||||
comments := (options & IniIncludeComments) != IniNone
|
||||
|
||||
for _, option := range group.options {
|
||||
if option.isFunc() || option.Hidden {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(option.tag.Get("no-ini")) != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
val := option.value
|
||||
|
||||
if (options&IniIncludeDefaults) == IniNone && option.valueIsDefault() {
|
||||
continue
|
||||
}
|
||||
|
||||
if !sectionwritten {
|
||||
fmt.Fprintf(writer, "[%s]\n", sname)
|
||||
sectionwritten = true
|
||||
}
|
||||
|
||||
if comments && len(option.Description) != 0 {
|
||||
fmt.Fprintf(writer, "; %s\n", option.Description)
|
||||
}
|
||||
|
||||
oname := optionIniName(option)
|
||||
|
||||
commentOption := (options&(IniIncludeDefaults|IniCommentDefaults)) == IniIncludeDefaults|IniCommentDefaults && option.valueIsDefault()
|
||||
|
||||
kind := val.Type().Kind()
|
||||
switch kind {
|
||||
case reflect.Slice:
|
||||
kind = val.Type().Elem().Kind()
|
||||
|
||||
if val.Len() == 0 {
|
||||
writeOption(writer, oname, kind, "", "", true, option.iniQuote)
|
||||
} else {
|
||||
for idx := 0; idx < val.Len(); idx++ {
|
||||
v, _ := convertToString(val.Index(idx), option.tag)
|
||||
|
||||
writeOption(writer, oname, kind, "", v, commentOption, option.iniQuote)
|
||||
}
|
||||
}
|
||||
case reflect.Map:
|
||||
kind = val.Type().Elem().Kind()
|
||||
|
||||
if val.Len() == 0 {
|
||||
writeOption(writer, oname, kind, "", "", true, option.iniQuote)
|
||||
} else {
|
||||
mkeys := val.MapKeys()
|
||||
keys := make([]string, len(val.MapKeys()))
|
||||
kkmap := make(map[string]reflect.Value)
|
||||
|
||||
for i, k := range mkeys {
|
||||
keys[i], _ = convertToString(k, option.tag)
|
||||
kkmap[keys[i]] = k
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
for _, k := range keys {
|
||||
v, _ := convertToString(val.MapIndex(kkmap[k]), option.tag)
|
||||
|
||||
writeOption(writer, oname, kind, k, v, commentOption, option.iniQuote)
|
||||
}
|
||||
}
|
||||
default:
|
||||
v, _ := convertToString(val, option.tag)
|
||||
|
||||
writeOption(writer, oname, kind, "", v, commentOption, option.iniQuote)
|
||||
}
|
||||
|
||||
if comments {
|
||||
fmt.Fprintln(writer)
|
||||
}
|
||||
}
|
||||
|
||||
if sectionwritten && !comments {
|
||||
fmt.Fprintln(writer)
|
||||
}
|
||||
}
|
||||
|
||||
func writeOption(writer io.Writer, optionName string, optionType reflect.Kind, optionKey string, optionValue string, commentOption bool, forceQuote bool) {
|
||||
if forceQuote || (optionType == reflect.String && !isPrint(optionValue)) {
|
||||
optionValue = strconv.Quote(optionValue)
|
||||
}
|
||||
|
||||
comment := ""
|
||||
if commentOption {
|
||||
comment = "; "
|
||||
}
|
||||
|
||||
fmt.Fprintf(writer, "%s%s =", comment, optionName)
|
||||
|
||||
if optionKey != "" {
|
||||
fmt.Fprintf(writer, " %s:%s", optionKey, optionValue)
|
||||
} else if optionValue != "" {
|
||||
fmt.Fprintf(writer, " %s", optionValue)
|
||||
}
|
||||
|
||||
fmt.Fprintln(writer)
|
||||
}
|
||||
|
||||
func writeCommandIni(command *Command, namespace string, writer io.Writer, options IniOptions) {
|
||||
command.eachGroup(func(group *Group) {
|
||||
if !group.Hidden {
|
||||
writeGroupIni(command, group, namespace, writer, options)
|
||||
}
|
||||
})
|
||||
|
||||
for _, c := range command.commands {
|
||||
var nns string
|
||||
|
||||
if c.Hidden {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(namespace) != 0 {
|
||||
nns = c.Name + "." + nns
|
||||
} else {
|
||||
nns = c.Name
|
||||
}
|
||||
|
||||
writeCommandIni(c, nns, writer, options)
|
||||
}
|
||||
}
|
||||
|
||||
func writeIni(parser *IniParser, writer io.Writer, options IniOptions) {
|
||||
writeCommandIni(parser.parser.Command, "", writer, options)
|
||||
}
|
||||
|
||||
func writeIniToFile(parser *IniParser, filename string, options IniOptions) error {
|
||||
file, err := os.Create(filename)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
writeIni(parser, file, options)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readIniFromFile(filename string) (*ini, error) {
|
||||
file, err := os.Open(filename)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
|
||||
return readIni(file, filename)
|
||||
}
|
||||
|
||||
func readIni(contents io.Reader, filename string) (*ini, error) {
|
||||
ret := &ini{
|
||||
File: filename,
|
||||
Sections: make(map[string]iniSection),
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(contents)
|
||||
|
||||
// Empty global section
|
||||
section := make(iniSection, 0, 10)
|
||||
sectionname := ""
|
||||
|
||||
ret.Sections[sectionname] = section
|
||||
|
||||
var lineno uint
|
||||
|
||||
for {
|
||||
line, err := readFullLine(reader)
|
||||
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lineno++
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
// Skip empty lines and lines starting with ; (comments)
|
||||
if len(line) == 0 || line[0] == ';' || line[0] == '#' {
|
||||
continue
|
||||
}
|
||||
|
||||
if line[0] == '[' {
|
||||
if line[0] != '[' || line[len(line)-1] != ']' {
|
||||
return nil, &IniError{
|
||||
Message: "malformed section header",
|
||||
File: filename,
|
||||
LineNumber: lineno,
|
||||
}
|
||||
}
|
||||
|
||||
name := strings.TrimSpace(line[1 : len(line)-1])
|
||||
|
||||
if len(name) == 0 {
|
||||
return nil, &IniError{
|
||||
Message: "empty section name",
|
||||
File: filename,
|
||||
LineNumber: lineno,
|
||||
}
|
||||
}
|
||||
|
||||
sectionname = name
|
||||
section = ret.Sections[name]
|
||||
|
||||
if section == nil {
|
||||
section = make(iniSection, 0, 10)
|
||||
ret.Sections[name] = section
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// Parse option here
|
||||
keyval := strings.SplitN(line, "=", 2)
|
||||
|
||||
if len(keyval) != 2 {
|
||||
return nil, &IniError{
|
||||
Message: fmt.Sprintf("malformed key=value (%s)", line),
|
||||
File: filename,
|
||||
LineNumber: lineno,
|
||||
}
|
||||
}
|
||||
|
||||
name := strings.TrimSpace(keyval[0])
|
||||
value := strings.TrimSpace(keyval[1])
|
||||
quoted := false
|
||||
|
||||
if len(value) != 0 && value[0] == '"' {
|
||||
if v, err := strconv.Unquote(value); err == nil {
|
||||
value = v
|
||||
|
||||
quoted = true
|
||||
} else {
|
||||
return nil, &IniError{
|
||||
Message: err.Error(),
|
||||
File: filename,
|
||||
LineNumber: lineno,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section = append(section, iniValue{
|
||||
Name: name,
|
||||
Value: value,
|
||||
Quoted: quoted,
|
||||
LineNumber: lineno,
|
||||
})
|
||||
|
||||
ret.Sections[sectionname] = section
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (i *IniParser) matchingGroups(name string) []*Group {
|
||||
if len(name) == 0 {
|
||||
var ret []*Group
|
||||
|
||||
i.parser.eachGroup(func(g *Group) {
|
||||
ret = append(ret, g)
|
||||
})
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
g := i.parser.groupByName(name)
|
||||
|
||||
if g != nil {
|
||||
return []*Group{g}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IniParser) parse(ini *ini) error {
|
||||
p := i.parser
|
||||
|
||||
var quotesLookup = make(map[*Option]bool)
|
||||
|
||||
for name, section := range ini.Sections {
|
||||
groups := i.matchingGroups(name)
|
||||
|
||||
if len(groups) == 0 {
|
||||
return newErrorf(ErrUnknownGroup, "could not find option group `%s'", name)
|
||||
}
|
||||
|
||||
for _, inival := range section {
|
||||
var opt *Option
|
||||
|
||||
for _, group := range groups {
|
||||
opt = group.optionByName(inival.Name, func(o *Option, n string) bool {
|
||||
return strings.ToLower(o.tag.Get("ini-name")) == strings.ToLower(n)
|
||||
})
|
||||
|
||||
if opt != nil && len(opt.tag.Get("no-ini")) != 0 {
|
||||
opt = nil
|
||||
}
|
||||
|
||||
if opt != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if opt == nil {
|
||||
if (p.Options & IgnoreUnknown) == None {
|
||||
return &IniError{
|
||||
Message: fmt.Sprintf("unknown option: %s", inival.Name),
|
||||
File: ini.File,
|
||||
LineNumber: inival.LineNumber,
|
||||
}
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// ini value is ignored if override is set and
|
||||
// value was previously set from non default
|
||||
if i.ParseAsDefaults && !opt.isSetDefault {
|
||||
continue
|
||||
}
|
||||
|
||||
pval := &inival.Value
|
||||
|
||||
if !opt.canArgument() && len(inival.Value) == 0 {
|
||||
pval = nil
|
||||
} else {
|
||||
if opt.value.Type().Kind() == reflect.Map {
|
||||
parts := strings.SplitN(inival.Value, ":", 2)
|
||||
|
||||
// only handle unquoting
|
||||
if len(parts) == 2 && parts[1][0] == '"' {
|
||||
if v, err := strconv.Unquote(parts[1]); err == nil {
|
||||
parts[1] = v
|
||||
|
||||
inival.Quoted = true
|
||||
} else {
|
||||
return &IniError{
|
||||
Message: err.Error(),
|
||||
File: ini.File,
|
||||
LineNumber: inival.LineNumber,
|
||||
}
|
||||
}
|
||||
|
||||
s := parts[0] + ":" + parts[1]
|
||||
|
||||
pval = &s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := opt.set(pval); err != nil {
|
||||
return &IniError{
|
||||
Message: err.Error(),
|
||||
File: ini.File,
|
||||
LineNumber: inival.LineNumber,
|
||||
}
|
||||
}
|
||||
|
||||
// either all INI values are quoted or only values who need quoting
|
||||
if _, ok := quotesLookup[opt]; !inival.Quoted || !ok {
|
||||
quotesLookup[opt] = inival.Quoted
|
||||
}
|
||||
|
||||
opt.tag.Set("_read-ini-name", inival.Name)
|
||||
}
|
||||
}
|
||||
|
||||
for opt, quoted := range quotesLookup {
|
||||
opt.iniQuote = quoted
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue