mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 10:02:26 -05:00 
			
		
		
		
	[bugfix] Fix Swagger spec and add test script (#2698)
* Add Swagger spec test script * Fix Swagger spec errors not related to statuses with polls * Add API tests that post a status with a poll * Fix creating a status with a poll from form params * Fix Swagger spec errors related to statuses with polls (this is the last error) * Fix Swagger spec warnings not related to unused definitions * Suppress a duplicate list update params definition that was somehow causing wrong param names * Add Swagger test to CI - updates Drone config - vendorizes go-swagger - fixes a file extension issue that caused the test script to generate JSON instead of YAML with the vendorized version * Put `Sample: ` on its own line everywhere * Remove unused id param from emojiCategoriesGet * Add 5 more pairs of profile fields to account update API Swagger * Remove Swagger prefix from dummy fields It makes the generated code look weird * Manually annotate params for statusCreate operation * Fix all remaining Swagger spec warnings - Change some models into operation parameters - Ignore models that already correspond to manually documented operation parameters but can't be trivially changed (those with file fields) * Documented that creating a status with scheduled_at isn't implemented yet * sign drone.yml * Fix filter API Swagger errors * fixup! Fix filter API Swagger errors --------- Co-authored-by: tobi <tobi.smethurst@protonmail.com>
This commit is contained in:
		
					parent
					
						
							
								68c8fe67cc
							
						
					
				
			
			
				commit
				
					
						fc3741365c
					
				
			
		
					 672 changed files with 135624 additions and 713 deletions
				
			
		
							
								
								
									
										569
									
								
								vendor/github.com/jessevdk/go-flags/option.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										569
									
								
								vendor/github.com/jessevdk/go-flags/option.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,569 @@ | |||
| package flags | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
| 	"unicode/utf8" | ||||
| ) | ||||
| 
 | ||||
| // Option flag information. Contains a description of the option, short and | ||||
| // long name as well as a default value and whether an argument for this | ||||
| // flag is optional. | ||||
| type Option struct { | ||||
| 	// The description of the option flag. This description is shown | ||||
| 	// automatically in the built-in help. | ||||
| 	Description string | ||||
| 
 | ||||
| 	// The short name of the option (a single character). If not 0, the | ||||
| 	// option flag can be 'activated' using -<ShortName>. Either ShortName | ||||
| 	// or LongName needs to be non-empty. | ||||
| 	ShortName rune | ||||
| 
 | ||||
| 	// The long name of the option. If not "", the option flag can be | ||||
| 	// activated using --<LongName>. Either ShortName or LongName needs | ||||
| 	// to be non-empty. | ||||
| 	LongName string | ||||
| 
 | ||||
| 	// The default value of the option. | ||||
| 	Default []string | ||||
| 
 | ||||
| 	// The optional environment default value key name. | ||||
| 	EnvDefaultKey string | ||||
| 
 | ||||
| 	// The optional delimiter string for EnvDefaultKey values. | ||||
| 	EnvDefaultDelim string | ||||
| 
 | ||||
| 	// If true, specifies that the argument to an option flag is optional. | ||||
| 	// When no argument to the flag is specified on the command line, the | ||||
| 	// value of OptionalValue will be set in the field this option represents. | ||||
| 	// This is only valid for non-boolean options. | ||||
| 	OptionalArgument bool | ||||
| 
 | ||||
| 	// The optional value of the option. The optional value is used when | ||||
| 	// the option flag is marked as having an OptionalArgument. This means | ||||
| 	// that when the flag is specified, but no option argument is given, | ||||
| 	// the value of the field this option represents will be set to | ||||
| 	// OptionalValue. This is only valid for non-boolean options. | ||||
| 	OptionalValue []string | ||||
| 
 | ||||
| 	// If true, the option _must_ be specified on the command line. If the | ||||
| 	// option is not specified, the parser will generate an ErrRequired type | ||||
| 	// error. | ||||
| 	Required bool | ||||
| 
 | ||||
| 	// A name for the value of an option shown in the Help as --flag [ValueName] | ||||
| 	ValueName string | ||||
| 
 | ||||
| 	// A mask value to show in the help instead of the default value. This | ||||
| 	// is useful for hiding sensitive information in the help, such as | ||||
| 	// passwords. | ||||
| 	DefaultMask string | ||||
| 
 | ||||
| 	// If non empty, only a certain set of values is allowed for an option. | ||||
| 	Choices []string | ||||
| 
 | ||||
| 	// If true, the option is not displayed in the help or man page | ||||
| 	Hidden bool | ||||
| 
 | ||||
| 	// The group which the option belongs to | ||||
| 	group *Group | ||||
| 
 | ||||
| 	// The struct field which the option represents. | ||||
| 	field reflect.StructField | ||||
| 
 | ||||
| 	// The struct field value which the option represents. | ||||
| 	value reflect.Value | ||||
| 
 | ||||
| 	// Determines if the option will be always quoted in the INI output | ||||
| 	iniQuote bool | ||||
| 
 | ||||
| 	tag                     multiTag | ||||
| 	isSet                   bool | ||||
| 	isSetDefault            bool | ||||
| 	preventDefault          bool | ||||
| 	clearReferenceBeforeSet bool | ||||
| 
 | ||||
| 	defaultLiteral string | ||||
| } | ||||
| 
 | ||||
| // LongNameWithNamespace returns the option's long name with the group namespaces | ||||
| // prepended by walking up the option's group tree. Namespaces and the long name | ||||
| // itself are separated by the parser's namespace delimiter. If the long name is | ||||
| // empty an empty string is returned. | ||||
| func (option *Option) LongNameWithNamespace() string { | ||||
| 	if len(option.LongName) == 0 { | ||||
| 		return "" | ||||
| 	} | ||||
| 
 | ||||
| 	// fetch the namespace delimiter from the parser which is always at the | ||||
| 	// end of the group hierarchy | ||||
| 	namespaceDelimiter := "" | ||||
| 	g := option.group | ||||
| 
 | ||||
| 	for { | ||||
| 		if p, ok := g.parent.(*Parser); ok { | ||||
| 			namespaceDelimiter = p.NamespaceDelimiter | ||||
| 
 | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		switch i := g.parent.(type) { | ||||
| 		case *Command: | ||||
| 			g = i.Group | ||||
| 		case *Group: | ||||
| 			g = i | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// concatenate long name with namespace | ||||
| 	longName := option.LongName | ||||
| 	g = option.group | ||||
| 
 | ||||
| 	for g != nil { | ||||
| 		if g.Namespace != "" { | ||||
| 			longName = g.Namespace + namespaceDelimiter + longName | ||||
| 		} | ||||
| 
 | ||||
| 		switch i := g.parent.(type) { | ||||
| 		case *Command: | ||||
| 			g = i.Group | ||||
| 		case *Group: | ||||
| 			g = i | ||||
| 		case *Parser: | ||||
| 			g = nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return longName | ||||
| } | ||||
| 
 | ||||
| // EnvKeyWithNamespace returns the option's env key with the group namespaces | ||||
| // prepended by walking up the option's group tree. Namespaces and the env key | ||||
| // itself are separated by the parser's namespace delimiter. If the env key is | ||||
| // empty an empty string is returned. | ||||
| func (option *Option) EnvKeyWithNamespace() string { | ||||
| 	if len(option.EnvDefaultKey) == 0 { | ||||
| 		return "" | ||||
| 	} | ||||
| 
 | ||||
| 	// fetch the namespace delimiter from the parser which is always at the | ||||
| 	// end of the group hierarchy | ||||
| 	namespaceDelimiter := "" | ||||
| 	g := option.group | ||||
| 
 | ||||
| 	for { | ||||
| 		if p, ok := g.parent.(*Parser); ok { | ||||
| 			namespaceDelimiter = p.EnvNamespaceDelimiter | ||||
| 
 | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		switch i := g.parent.(type) { | ||||
| 		case *Command: | ||||
| 			g = i.Group | ||||
| 		case *Group: | ||||
| 			g = i | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// concatenate long name with namespace | ||||
| 	key := option.EnvDefaultKey | ||||
| 	g = option.group | ||||
| 
 | ||||
| 	for g != nil { | ||||
| 		if g.EnvNamespace != "" { | ||||
| 			key = g.EnvNamespace + namespaceDelimiter + key | ||||
| 		} | ||||
| 
 | ||||
| 		switch i := g.parent.(type) { | ||||
| 		case *Command: | ||||
| 			g = i.Group | ||||
| 		case *Group: | ||||
| 			g = i | ||||
| 		case *Parser: | ||||
| 			g = nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return key | ||||
| } | ||||
| 
 | ||||
| // String converts an option to a human friendly readable string describing the | ||||
| // option. | ||||
| func (option *Option) String() string { | ||||
| 	var s string | ||||
| 	var short string | ||||
| 
 | ||||
| 	if option.ShortName != 0 { | ||||
| 		data := make([]byte, utf8.RuneLen(option.ShortName)) | ||||
| 		utf8.EncodeRune(data, option.ShortName) | ||||
| 		short = string(data) | ||||
| 
 | ||||
| 		if len(option.LongName) != 0 { | ||||
| 			s = fmt.Sprintf("%s%s, %s%s", | ||||
| 				string(defaultShortOptDelimiter), short, | ||||
| 				defaultLongOptDelimiter, option.LongNameWithNamespace()) | ||||
| 		} else { | ||||
| 			s = fmt.Sprintf("%s%s", string(defaultShortOptDelimiter), short) | ||||
| 		} | ||||
| 	} else if len(option.LongName) != 0 { | ||||
| 		s = fmt.Sprintf("%s%s", defaultLongOptDelimiter, option.LongNameWithNamespace()) | ||||
| 	} | ||||
| 
 | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| // Value returns the option value as an interface{}. | ||||
| func (option *Option) Value() interface{} { | ||||
| 	return option.value.Interface() | ||||
| } | ||||
| 
 | ||||
| // Field returns the reflect struct field of the option. | ||||
| func (option *Option) Field() reflect.StructField { | ||||
| 	return option.field | ||||
| } | ||||
| 
 | ||||
| // IsSet returns true if option has been set | ||||
| func (option *Option) IsSet() bool { | ||||
| 	return option.isSet | ||||
| } | ||||
| 
 | ||||
| // IsSetDefault returns true if option has been set via the default option tag | ||||
| func (option *Option) IsSetDefault() bool { | ||||
| 	return option.isSetDefault | ||||
| } | ||||
| 
 | ||||
| // Set the value of an option to the specified value. An error will be returned | ||||
| // if the specified value could not be converted to the corresponding option | ||||
| // value type. | ||||
| func (option *Option) set(value *string) error { | ||||
| 	kind := option.value.Type().Kind() | ||||
| 
 | ||||
| 	if (kind == reflect.Map || kind == reflect.Slice) && option.clearReferenceBeforeSet { | ||||
| 		option.empty() | ||||
| 	} | ||||
| 
 | ||||
| 	option.isSet = true | ||||
| 	option.preventDefault = true | ||||
| 	option.clearReferenceBeforeSet = false | ||||
| 
 | ||||
| 	if len(option.Choices) != 0 { | ||||
| 		found := false | ||||
| 
 | ||||
| 		for _, choice := range option.Choices { | ||||
| 			if choice == *value { | ||||
| 				found = true | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if !found { | ||||
| 			allowed := strings.Join(option.Choices[0:len(option.Choices)-1], ", ") | ||||
| 
 | ||||
| 			if len(option.Choices) > 1 { | ||||
| 				allowed += " or " + option.Choices[len(option.Choices)-1] | ||||
| 			} | ||||
| 
 | ||||
| 			return newErrorf(ErrInvalidChoice, | ||||
| 				"Invalid value `%s' for option `%s'. Allowed values are: %s", | ||||
| 				*value, option, allowed) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if option.isFunc() { | ||||
| 		return option.call(value) | ||||
| 	} else if value != nil { | ||||
| 		return convert(*value, option.value, option.tag) | ||||
| 	} | ||||
| 
 | ||||
| 	return convert("", option.value, option.tag) | ||||
| } | ||||
| 
 | ||||
| func (option *Option) setDefault(value *string) error { | ||||
| 	if option.preventDefault { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	if err := option.set(value); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	option.isSetDefault = true | ||||
| 	option.preventDefault = false | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (option *Option) showInHelp() bool { | ||||
| 	return !option.Hidden && (option.ShortName != 0 || len(option.LongName) != 0) | ||||
| } | ||||
| 
 | ||||
| func (option *Option) canArgument() bool { | ||||
| 	if u := option.isUnmarshaler(); u != nil { | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	return !option.isBool() | ||||
| } | ||||
| 
 | ||||
| func (option *Option) emptyValue() reflect.Value { | ||||
| 	tp := option.value.Type() | ||||
| 
 | ||||
| 	if tp.Kind() == reflect.Map { | ||||
| 		return reflect.MakeMap(tp) | ||||
| 	} | ||||
| 
 | ||||
| 	return reflect.Zero(tp) | ||||
| } | ||||
| 
 | ||||
| func (option *Option) empty() { | ||||
| 	if !option.isFunc() { | ||||
| 		option.value.Set(option.emptyValue()) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (option *Option) clearDefault() error { | ||||
| 	if option.preventDefault { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	usedDefault := option.Default | ||||
| 
 | ||||
| 	if envKey := option.EnvKeyWithNamespace(); envKey != "" { | ||||
| 		if value, ok := os.LookupEnv(envKey); ok { | ||||
| 			if option.EnvDefaultDelim != "" { | ||||
| 				usedDefault = strings.Split(value, option.EnvDefaultDelim) | ||||
| 			} else { | ||||
| 				usedDefault = []string{value} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	option.isSetDefault = true | ||||
| 
 | ||||
| 	if len(usedDefault) > 0 { | ||||
| 		option.empty() | ||||
| 
 | ||||
| 		for _, d := range usedDefault { | ||||
| 			err := option.setDefault(&d) | ||||
| 
 | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
| 		tp := option.value.Type() | ||||
| 
 | ||||
| 		switch tp.Kind() { | ||||
| 		case reflect.Map: | ||||
| 			if option.value.IsNil() { | ||||
| 				option.empty() | ||||
| 			} | ||||
| 		case reflect.Slice: | ||||
| 			if option.value.IsNil() { | ||||
| 				option.empty() | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (option *Option) valueIsDefault() bool { | ||||
| 	// Check if the value of the option corresponds to its | ||||
| 	// default value | ||||
| 	emptyval := option.emptyValue() | ||||
| 
 | ||||
| 	checkvalptr := reflect.New(emptyval.Type()) | ||||
| 	checkval := reflect.Indirect(checkvalptr) | ||||
| 
 | ||||
| 	checkval.Set(emptyval) | ||||
| 
 | ||||
| 	if len(option.Default) != 0 { | ||||
| 		for _, v := range option.Default { | ||||
| 			convert(v, checkval, option.tag) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return reflect.DeepEqual(option.value.Interface(), checkval.Interface()) | ||||
| } | ||||
| 
 | ||||
| func (option *Option) isUnmarshaler() Unmarshaler { | ||||
| 	v := option.value | ||||
| 
 | ||||
| 	for { | ||||
| 		if !v.CanInterface() { | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		i := v.Interface() | ||||
| 
 | ||||
| 		if u, ok := i.(Unmarshaler); ok { | ||||
| 			return u | ||||
| 		} | ||||
| 
 | ||||
| 		if !v.CanAddr() { | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		v = v.Addr() | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (option *Option) isValueValidator() ValueValidator { | ||||
| 	v := option.value | ||||
| 
 | ||||
| 	for { | ||||
| 		if !v.CanInterface() { | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		i := v.Interface() | ||||
| 
 | ||||
| 		if u, ok := i.(ValueValidator); ok { | ||||
| 			return u | ||||
| 		} | ||||
| 
 | ||||
| 		if !v.CanAddr() { | ||||
| 			break | ||||
| 		} | ||||
| 
 | ||||
| 		v = v.Addr() | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (option *Option) isBool() bool { | ||||
| 	tp := option.value.Type() | ||||
| 
 | ||||
| 	for { | ||||
| 		switch tp.Kind() { | ||||
| 		case reflect.Slice, reflect.Ptr: | ||||
| 			tp = tp.Elem() | ||||
| 		case reflect.Bool: | ||||
| 			return true | ||||
| 		case reflect.Func: | ||||
| 			return tp.NumIn() == 0 | ||||
| 		default: | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (option *Option) isSignedNumber() bool { | ||||
| 	tp := option.value.Type() | ||||
| 
 | ||||
| 	for { | ||||
| 		switch tp.Kind() { | ||||
| 		case reflect.Slice, reflect.Ptr: | ||||
| 			tp = tp.Elem() | ||||
| 		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64: | ||||
| 			return true | ||||
| 		default: | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (option *Option) isFunc() bool { | ||||
| 	return option.value.Type().Kind() == reflect.Func | ||||
| } | ||||
| 
 | ||||
| func (option *Option) call(value *string) error { | ||||
| 	var retval []reflect.Value | ||||
| 
 | ||||
| 	if value == nil { | ||||
| 		retval = option.value.Call(nil) | ||||
| 	} else { | ||||
| 		tp := option.value.Type().In(0) | ||||
| 
 | ||||
| 		val := reflect.New(tp) | ||||
| 		val = reflect.Indirect(val) | ||||
| 
 | ||||
| 		if err := convert(*value, val, option.tag); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		retval = option.value.Call([]reflect.Value{val}) | ||||
| 	} | ||||
| 
 | ||||
| 	if len(retval) == 1 && retval[0].Type() == reflect.TypeOf((*error)(nil)).Elem() { | ||||
| 		if retval[0].Interface() == nil { | ||||
| 			return nil | ||||
| 		} | ||||
| 
 | ||||
| 		return retval[0].Interface().(error) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (option *Option) updateDefaultLiteral() { | ||||
| 	defs := option.Default | ||||
| 	def := "" | ||||
| 
 | ||||
| 	if len(defs) == 0 && option.canArgument() { | ||||
| 		var showdef bool | ||||
| 
 | ||||
| 		switch option.field.Type.Kind() { | ||||
| 		case reflect.Func, reflect.Ptr: | ||||
| 			showdef = !option.value.IsNil() | ||||
| 		case reflect.Slice, reflect.String, reflect.Array: | ||||
| 			showdef = option.value.Len() > 0 | ||||
| 		case reflect.Map: | ||||
| 			showdef = !option.value.IsNil() && option.value.Len() > 0 | ||||
| 		default: | ||||
| 			zeroval := reflect.Zero(option.field.Type) | ||||
| 			showdef = !reflect.DeepEqual(zeroval.Interface(), option.value.Interface()) | ||||
| 		} | ||||
| 
 | ||||
| 		if showdef { | ||||
| 			def, _ = convertToString(option.value, option.tag) | ||||
| 		} | ||||
| 	} else if len(defs) != 0 { | ||||
| 		l := len(defs) - 1 | ||||
| 
 | ||||
| 		for i := 0; i < l; i++ { | ||||
| 			def += quoteIfNeeded(defs[i]) + ", " | ||||
| 		} | ||||
| 
 | ||||
| 		def += quoteIfNeeded(defs[l]) | ||||
| 	} | ||||
| 
 | ||||
| 	option.defaultLiteral = def | ||||
| } | ||||
| 
 | ||||
| func (option *Option) shortAndLongName() string { | ||||
| 	ret := &bytes.Buffer{} | ||||
| 
 | ||||
| 	if option.ShortName != 0 { | ||||
| 		ret.WriteRune(defaultShortOptDelimiter) | ||||
| 		ret.WriteRune(option.ShortName) | ||||
| 	} | ||||
| 
 | ||||
| 	if len(option.LongName) != 0 { | ||||
| 		if option.ShortName != 0 { | ||||
| 			ret.WriteRune('/') | ||||
| 		} | ||||
| 
 | ||||
| 		ret.WriteString(option.LongName) | ||||
| 	} | ||||
| 
 | ||||
| 	return ret.String() | ||||
| } | ||||
| 
 | ||||
| func (option *Option) isValidValue(arg string) error { | ||||
| 	if validator := option.isValueValidator(); validator != nil { | ||||
| 		return validator.IsValidValue(arg) | ||||
| 	} | ||||
| 	if argumentIsOption(arg) && !(option.isSignedNumber() && len(arg) > 1 && arg[0] == '-' && arg[1] >= '0' && arg[1] <= '9') { | ||||
| 		return fmt.Errorf("expected argument for flag `%s', but got option `%s'", option, arg) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue