mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 03:32:25 -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
				
			
		
							
								
								
									
										293
									
								
								vendor/github.com/go-openapi/analysis/flatten_name.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										293
									
								
								vendor/github.com/go-openapi/analysis/flatten_name.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,293 @@ | |||
| package analysis | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"path" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/go-openapi/analysis/internal/flatten/operations" | ||||
| 	"github.com/go-openapi/analysis/internal/flatten/replace" | ||||
| 	"github.com/go-openapi/analysis/internal/flatten/schutils" | ||||
| 	"github.com/go-openapi/analysis/internal/flatten/sortref" | ||||
| 	"github.com/go-openapi/spec" | ||||
| 	"github.com/go-openapi/swag" | ||||
| ) | ||||
| 
 | ||||
| // InlineSchemaNamer finds a new name for an inlined type | ||||
| type InlineSchemaNamer struct { | ||||
| 	Spec           *spec.Swagger | ||||
| 	Operations     map[string]operations.OpRef | ||||
| 	flattenContext *context | ||||
| 	opts           *FlattenOpts | ||||
| } | ||||
| 
 | ||||
| // Name yields a new name for the inline schema | ||||
| func (isn *InlineSchemaNamer) Name(key string, schema *spec.Schema, aschema *AnalyzedSchema) error { | ||||
| 	debugLog("naming inlined schema at %s", key) | ||||
| 
 | ||||
| 	parts := sortref.KeyParts(key) | ||||
| 	for _, name := range namesFromKey(parts, aschema, isn.Operations) { | ||||
| 		if name == "" { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		// create unique name | ||||
| 		newName, isOAIGen := uniqifyName(isn.Spec.Definitions, swag.ToJSONName(name)) | ||||
| 
 | ||||
| 		// clone schema | ||||
| 		sch := schutils.Clone(schema) | ||||
| 
 | ||||
| 		// replace values on schema | ||||
| 		if err := replace.RewriteSchemaToRef(isn.Spec, key, | ||||
| 			spec.MustCreateRef(path.Join(definitionsPath, newName))); err != nil { | ||||
| 			return fmt.Errorf("error while creating definition %q from inline schema: %w", newName, err) | ||||
| 		} | ||||
| 
 | ||||
| 		// rewrite any dependent $ref pointing to this place, | ||||
| 		// when not already pointing to a top-level definition. | ||||
| 		// | ||||
| 		// NOTE: this is important if such referers use arbitrary JSON pointers. | ||||
| 		an := New(isn.Spec) | ||||
| 		for k, v := range an.references.allRefs { | ||||
| 			r, erd := replace.DeepestRef(isn.opts.Swagger(), isn.opts.ExpandOpts(false), v) | ||||
| 			if erd != nil { | ||||
| 				return fmt.Errorf("at %s, %w", k, erd) | ||||
| 			} | ||||
| 
 | ||||
| 			if isn.opts.flattenContext != nil { | ||||
| 				isn.opts.flattenContext.warnings = append(isn.opts.flattenContext.warnings, r.Warnings...) | ||||
| 			} | ||||
| 
 | ||||
| 			if r.Ref.String() != key && (r.Ref.String() != path.Join(definitionsPath, newName) || path.Dir(v.String()) == definitionsPath) { | ||||
| 				continue | ||||
| 			} | ||||
| 
 | ||||
| 			debugLog("found a $ref to a rewritten schema: %s points to %s", k, v.String()) | ||||
| 
 | ||||
| 			// rewrite $ref to the new target | ||||
| 			if err := replace.UpdateRef(isn.Spec, k, | ||||
| 				spec.MustCreateRef(path.Join(definitionsPath, newName))); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// NOTE: this extension is currently not used by go-swagger (provided for information only) | ||||
| 		sch.AddExtension("x-go-gen-location", GenLocation(parts)) | ||||
| 
 | ||||
| 		// save cloned schema to definitions | ||||
| 		schutils.Save(isn.Spec, newName, sch) | ||||
| 
 | ||||
| 		// keep track of created refs | ||||
| 		if isn.flattenContext == nil { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		debugLog("track created ref: key=%s, newName=%s, isOAIGen=%t", key, newName, isOAIGen) | ||||
| 		resolved := false | ||||
| 
 | ||||
| 		if _, ok := isn.flattenContext.newRefs[key]; ok { | ||||
| 			resolved = isn.flattenContext.newRefs[key].resolved | ||||
| 		} | ||||
| 
 | ||||
| 		isn.flattenContext.newRefs[key] = &newRef{ | ||||
| 			key:      key, | ||||
| 			newName:  newName, | ||||
| 			path:     path.Join(definitionsPath, newName), | ||||
| 			isOAIGen: isOAIGen, | ||||
| 			resolved: resolved, | ||||
| 			schema:   sch, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // uniqifyName yields a unique name for a definition | ||||
| func uniqifyName(definitions spec.Definitions, name string) (string, bool) { | ||||
| 	isOAIGen := false | ||||
| 	if name == "" { | ||||
| 		name = "oaiGen" | ||||
| 		isOAIGen = true | ||||
| 	} | ||||
| 
 | ||||
| 	if len(definitions) == 0 { | ||||
| 		return name, isOAIGen | ||||
| 	} | ||||
| 
 | ||||
| 	unq := true | ||||
| 	for k := range definitions { | ||||
| 		if strings.EqualFold(k, name) { | ||||
| 			unq = false | ||||
| 
 | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if unq { | ||||
| 		return name, isOAIGen | ||||
| 	} | ||||
| 
 | ||||
| 	name += "OAIGen" | ||||
| 	isOAIGen = true | ||||
| 	var idx int | ||||
| 	unique := name | ||||
| 	_, known := definitions[unique] | ||||
| 
 | ||||
| 	for known { | ||||
| 		idx++ | ||||
| 		unique = fmt.Sprintf("%s%d", name, idx) | ||||
| 		_, known = definitions[unique] | ||||
| 	} | ||||
| 
 | ||||
| 	return unique, isOAIGen | ||||
| } | ||||
| 
 | ||||
| func namesFromKey(parts sortref.SplitKey, aschema *AnalyzedSchema, operations map[string]operations.OpRef) []string { | ||||
| 	var ( | ||||
| 		baseNames  [][]string | ||||
| 		startIndex int | ||||
| 	) | ||||
| 
 | ||||
| 	if parts.IsOperation() { | ||||
| 		baseNames, startIndex = namesForOperation(parts, operations) | ||||
| 	} | ||||
| 
 | ||||
| 	// definitions | ||||
| 	if parts.IsDefinition() { | ||||
| 		baseNames, startIndex = namesForDefinition(parts) | ||||
| 	} | ||||
| 
 | ||||
| 	result := make([]string, 0, len(baseNames)) | ||||
| 	for _, segments := range baseNames { | ||||
| 		nm := parts.BuildName(segments, startIndex, partAdder(aschema)) | ||||
| 		if nm == "" { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		result = append(result, nm) | ||||
| 	} | ||||
| 	sort.Strings(result) | ||||
| 
 | ||||
| 	return result | ||||
| } | ||||
| 
 | ||||
| func namesForParam(parts sortref.SplitKey, operations map[string]operations.OpRef) ([][]string, int) { | ||||
| 	var ( | ||||
| 		baseNames  [][]string | ||||
| 		startIndex int | ||||
| 	) | ||||
| 
 | ||||
| 	piref := parts.PathItemRef() | ||||
| 	if piref.String() != "" && parts.IsOperationParam() { | ||||
| 		if op, ok := operations[piref.String()]; ok { | ||||
| 			startIndex = 5 | ||||
| 			baseNames = append(baseNames, []string{op.ID, "params", "body"}) | ||||
| 		} | ||||
| 	} else if parts.IsSharedOperationParam() { | ||||
| 		pref := parts.PathRef() | ||||
| 		for k, v := range operations { | ||||
| 			if strings.HasPrefix(k, pref.String()) { | ||||
| 				startIndex = 4 | ||||
| 				baseNames = append(baseNames, []string{v.ID, "params", "body"}) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return baseNames, startIndex | ||||
| } | ||||
| 
 | ||||
| func namesForOperation(parts sortref.SplitKey, operations map[string]operations.OpRef) ([][]string, int) { | ||||
| 	var ( | ||||
| 		baseNames  [][]string | ||||
| 		startIndex int | ||||
| 	) | ||||
| 
 | ||||
| 	// params | ||||
| 	if parts.IsOperationParam() || parts.IsSharedOperationParam() { | ||||
| 		baseNames, startIndex = namesForParam(parts, operations) | ||||
| 	} | ||||
| 
 | ||||
| 	// responses | ||||
| 	if parts.IsOperationResponse() { | ||||
| 		piref := parts.PathItemRef() | ||||
| 		if piref.String() != "" { | ||||
| 			if op, ok := operations[piref.String()]; ok { | ||||
| 				startIndex = 6 | ||||
| 				baseNames = append(baseNames, []string{op.ID, parts.ResponseName(), "body"}) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return baseNames, startIndex | ||||
| } | ||||
| 
 | ||||
| func namesForDefinition(parts sortref.SplitKey) ([][]string, int) { | ||||
| 	nm := parts.DefinitionName() | ||||
| 	if nm != "" { | ||||
| 		return [][]string{{parts.DefinitionName()}}, 2 | ||||
| 	} | ||||
| 
 | ||||
| 	return [][]string{}, 0 | ||||
| } | ||||
| 
 | ||||
| // partAdder knows how to interpret a schema when it comes to build a name from parts | ||||
| func partAdder(aschema *AnalyzedSchema) sortref.PartAdder { | ||||
| 	return func(part string) []string { | ||||
| 		segments := make([]string, 0, 2) | ||||
| 
 | ||||
| 		if part == "items" || part == "additionalItems" { | ||||
| 			if aschema.IsTuple || aschema.IsTupleWithExtra { | ||||
| 				segments = append(segments, "tuple") | ||||
| 			} else { | ||||
| 				segments = append(segments, "items") | ||||
| 			} | ||||
| 
 | ||||
| 			if part == "additionalItems" { | ||||
| 				segments = append(segments, part) | ||||
| 			} | ||||
| 
 | ||||
| 			return segments | ||||
| 		} | ||||
| 
 | ||||
| 		segments = append(segments, part) | ||||
| 
 | ||||
| 		return segments | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func nameFromRef(ref spec.Ref) string { | ||||
| 	u := ref.GetURL() | ||||
| 	if u.Fragment != "" { | ||||
| 		return swag.ToJSONName(path.Base(u.Fragment)) | ||||
| 	} | ||||
| 
 | ||||
| 	if u.Path != "" { | ||||
| 		bn := path.Base(u.Path) | ||||
| 		if bn != "" && bn != "/" { | ||||
| 			ext := path.Ext(bn) | ||||
| 			if ext != "" { | ||||
| 				return swag.ToJSONName(bn[:len(bn)-len(ext)]) | ||||
| 			} | ||||
| 
 | ||||
| 			return swag.ToJSONName(bn) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return swag.ToJSONName(strings.ReplaceAll(u.Host, ".", " ")) | ||||
| } | ||||
| 
 | ||||
| // GenLocation indicates from which section of the specification (models or operations) a definition has been created. | ||||
| // | ||||
| // This is reflected in the output spec with a "x-go-gen-location" extension. At the moment, this is is provided | ||||
| // for information only. | ||||
| func GenLocation(parts sortref.SplitKey) string { | ||||
| 	switch { | ||||
| 	case parts.IsOperation(): | ||||
| 		return "operations" | ||||
| 	case parts.IsDefinition(): | ||||
| 		return "models" | ||||
| 	default: | ||||
| 		return "" | ||||
| 	} | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue