diff options
| author | 2025-11-03 13:55:04 +0100 | |
|---|---|---|
| committer | 2025-11-17 14:12:09 +0100 | |
| commit | 81e3cdda44a2aed1ad0805fa738429c891b6209d (patch) | |
| tree | d9c3c95eb721e1dc1c613ee7370eaad9ec8796f7 /vendor/github.com/go-swagger | |
| parent | [chore] add a 'nos3' build tag to support compiling without S3 storage suppor... (diff) | |
| download | gotosocial-81e3cdda44a2aed1ad0805fa738429c891b6209d.tar.xz | |
[chore] update dependencies (#4539)
- github.com/KimMachineGun/automemlimit: v0.7.4 -> v0.7.5
- github.com/tdewolff/minify/v2: v2.24.4 -> v2.24.5
- modernc.org/sqlite: v1.39.1 -> v1.40.0 w/ concurrency workaround
- github.com/go-swagger/go-swagger: v0.32.3 -> v0.33.1 (and drops use of our custom fork now the fix is available upstream)
Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4539
Co-authored-by: kim <grufwub@gmail.com>
Co-committed-by: kim <grufwub@gmail.com>
Diffstat (limited to 'vendor/github.com/go-swagger')
71 files changed, 2468 insertions, 1115 deletions
diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff.go index 2faba2537..f1579f163 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff.go @@ -9,6 +9,7 @@ import ( "os" "github.com/go-openapi/loads" + "github.com/go-swagger/go-swagger/cmd/swagger/commands/diff" ) @@ -42,7 +43,7 @@ func (c *DiffCommand) Execute(_ []string) error { err error ) if c.Destination != "stdout" { - output, err = os.OpenFile(c.Destination, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600) + output, err = os.OpenFile(c.Destination, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o600) if err != nil { return fmt.Errorf("%s: %w", c.Destination, err) } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/checks.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/checks.go index 627bc5f7b..ba9fa008b 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/checks.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/checks.go @@ -76,7 +76,6 @@ func CompareProperties(location DifferenceLocation, schema1 *spec.Schema, schema } } return propDiffs - } // CompareFloatValues compares a float data item @@ -123,7 +122,6 @@ func CompareIntValues(fieldName string, val1 *int64, val2 *int64, ifGreaterCode // CheckToFromPrimitiveType check for diff to or from a primitive func CheckToFromPrimitiveType(diffs []TypeDiff, type1, type2 interface{}) []TypeDiff { - type1IsPrimitive := isPrimitive(type1) type2IsPrimitive := isPrimitive(type2) @@ -139,7 +137,6 @@ func CheckToFromPrimitiveType(diffs []TypeDiff, type1, type2 interface{}) []Type // CheckRefChange has the property ref changed func CheckRefChange(diffs []TypeDiff, type1, type2 interface{}) (diffReturn []TypeDiff) { - diffReturn = diffs if isRefType(type1) && isRefType(type2) { // both refs but to different objects (TODO detect renamed object) diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/node.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/node.go index e1c7c95f1..74b57796a 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/node.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/node.go @@ -30,7 +30,6 @@ func (n *Node) String() string { // AddLeafNode Adds (recursive) a Child to the first non-nil child found func (n *Node) AddLeafNode(toAdd *Node) *Node { - if n.ChildNode == nil { n.ChildNode = toAdd } else { diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/schema.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/schema.go index 0874154bb..52464a9ba 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/schema.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/schema.go @@ -18,7 +18,6 @@ func getTypeFromSchema(schema *spec.Schema) (typeName string, isArray bool) { return typeName, true } return typeName, false - } func getTypeFromSimpleSchema(schema *spec.SimpleSchema) (typeName string, isArray bool) { @@ -32,7 +31,6 @@ func getTypeFromSimpleSchema(schema *spec.SimpleSchema) (typeName string, isArra return typeName, true } return typeName, false - } func getTypeFromSchemaProps(schema *spec.SchemaProps) (typeName string, isArray bool) { @@ -52,7 +50,6 @@ func getTypeFromSchemaProps(schema *spec.SchemaProps) (typeName string, isArray } } return typeName, false - } func getSchemaTypeStr(item interface{}) string { @@ -61,7 +58,6 @@ func getSchemaTypeStr(item interface{}) string { } func getSchemaType(item interface{}) (typeName string, isArray bool) { - switch s := item.(type) { case *spec.Schema: typeName, isArray = getTypeFromSchema(s) @@ -78,7 +74,6 @@ func getSchemaType(item interface{}) (typeName string, isArray bool) { } return - } func formatTypeString(typ string, isarray bool) string { diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_analyser.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_analyser.go index 655af1465..d3b74fa44 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_analyser.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_analyser.go @@ -3,7 +3,9 @@ package diff import ( "fmt" "reflect" - "strings" + + "golang.org/x/text/cases" + "golang.org/x/text/language" "github.com/go-openapi/spec" ) @@ -20,7 +22,7 @@ type URLMethodResponse struct { // MarshalText - for serializing as a map key func (p URLMethod) MarshalText() (text []byte, err error) { - return []byte(fmt.Sprintf("%s %s", p.Path, p.Method)), nil + return fmt.Appendf([]byte{}, "%s %s", p.Path, p.Method), nil } // URLMethods allows iteration of endpoints based on url and method @@ -38,6 +40,7 @@ type SpecAnalyser struct { ReferencedDefinitions map[string]bool schemasCompared map[string]struct{} + titler cases.Caser } // NewSpecAnalyser returns an empty SpecDiffs @@ -45,6 +48,7 @@ func NewSpecAnalyser() *SpecAnalyser { return &SpecAnalyser{ Diffs: SpecDifferences{}, ReferencedDefinitions: map[string]bool{}, + titler: cases.Title(language.English, cases.NoLower), } } @@ -155,7 +159,6 @@ func (sd *SpecAnalyser) AnalyseDefinitions() { } func (sd *SpecAnalyser) analyseEndpointData() { - for URLMethod, op2 := range sd.urlMethods2 { if op1, ok := sd.urlMethods1[URLMethod]; ok { addedTags, deletedTags, _ := fromStringArray(op1.Operation.Tags).DiffsTo(op2.Operation.Tags) @@ -178,7 +181,8 @@ func (sd *SpecAnalyser) analyseRequestParams() { locations := []string{"query", "path", "body", "header", "formData"} for _, paramLocation := range locations { - rootNode := getNameOnlyDiffNode(strings.Title(paramLocation)) + rootNode := getNameOnlyDiffNode(sd.titler.String(paramLocation)) + sd.titler.Reset() for URLMethod, op2 := range sd.urlMethods2 { if op1, ok := sd.urlMethods1[URLMethod]; ok { @@ -221,7 +225,6 @@ func (sd *SpecAnalyser) analyseRequestParams() { func (sd *SpecAnalyser) analyseResponseParams() { // Loop through url+methods in spec 2 - check deleted and changed for eachURLMethodFrom2, op2 := range sd.urlMethods2 { - // present in both specs? Use key from spec 2 to lookup in spec 1 if op1, ok := sd.urlMethods1[eachURLMethodFrom2]; ok { // compare responses for url and method @@ -246,27 +249,29 @@ func (sd *SpecAnalyser) analyseResponseParams() { // Added updated Response Codes for code2, op2Response := range op2Responses { if op1Response, ok := op1Responses[code2]; ok { - op1Headers := op1Response.ResponseProps.Headers + op1Headers := op1Response.Headers headerRootNode := getNameOnlyDiffNode("Headers") // Iterate Spec2 Headers looking for added and updated location := DifferenceLocation{URL: eachURLMethodFrom2.Path, Method: eachURLMethodFrom2.Method, Response: code2, Node: headerRootNode} - for op2HeaderName, op2Header := range op2Response.ResponseProps.Headers { + for op2HeaderName, op2Header := range op2Response.Headers { if op1Header, ok := op1Headers[op2HeaderName]; ok { diffs := sd.CompareProps(forHeader(op1Header), forHeader(op2Header)) sd.addDiffs(location, diffs) } else { sd.Diffs = sd.Diffs.addDiff(SpecDifference{ DifferenceLocation: location.AddNode(getSchemaDiffNode(op2HeaderName, &op2Header.SimpleSchema)), - Code: AddedResponseHeader}) + Code: AddedResponseHeader, + }) } } - for op1HeaderName := range op1Response.ResponseProps.Headers { - if _, ok := op2Response.ResponseProps.Headers[op1HeaderName]; !ok { - op1Header := op1Response.ResponseProps.Headers[op1HeaderName] + for op1HeaderName := range op1Response.Headers { + if _, ok := op2Response.Headers[op1HeaderName]; !ok { + op1Header := op1Response.Headers[op1HeaderName] sd.Diffs = sd.Diffs.addDiff(SpecDifference{ DifferenceLocation: location.AddNode(getSchemaDiffNode(op1HeaderName, &op1Header.SimpleSchema)), - Code: DeletedResponseHeader}) + Code: DeletedResponseHeader, + }) } } schem := op1Response.Schema @@ -274,17 +279,20 @@ func (sd *SpecAnalyser) analyseResponseParams() { if schem != nil { node = getSchemaDiffNode("Body", &schem.SchemaProps) } - responseLocation := DifferenceLocation{URL: eachURLMethodFrom2.Path, + responseLocation := DifferenceLocation{ + URL: eachURLMethodFrom2.Path, Method: eachURLMethodFrom2.Method, Response: code2, - Node: node} + Node: node, + } sd.compareDescripton(responseLocation, op1Response.Description, op2Response.Description) if op1Response.Schema != nil { if op2Response.Schema == nil { sd.Diffs = sd.Diffs.addDiff(SpecDifference{ DifferenceLocation: DifferenceLocation{URL: eachURLMethodFrom2.Path, Method: eachURLMethodFrom2.Method, Response: code2, Node: getSchemaDiffNode("Body", op1Response.Schema)}, - Code: DeletedProperty}) + Code: DeletedProperty, + }) } else { sd.compareSchema( DifferenceLocation{URL: eachURLMethodFrom2.Path, Method: eachURLMethodFrom2.Method, Response: code2, Node: getSchemaDiffNode("Body", op1Response.Schema)}, @@ -294,14 +302,16 @@ func (sd *SpecAnalyser) analyseResponseParams() { } else if op2Response.Schema != nil { sd.Diffs = sd.Diffs.addDiff(SpecDifference{ DifferenceLocation: DifferenceLocation{URL: eachURLMethodFrom2.Path, Method: eachURLMethodFrom2.Method, Response: code2, Node: getSchemaDiffNode("Body", op2Response.Schema)}, - Code: AddedProperty}) + Code: AddedProperty, + }) } } else { // op2Response sd.Diffs = sd.Diffs.addDiff(SpecDifference{ DifferenceLocation: DifferenceLocation{URL: eachURLMethodFrom2.Path, Method: eachURLMethodFrom2.Method, Response: code2, Node: getSchemaDiffNode("Body", op2Response.Schema)}, - Code: AddedResponse}) + Code: AddedResponse, + }) } } } @@ -538,7 +548,6 @@ func addTypeDiff(diffs []TypeDiff, diff TypeDiff) []TypeDiff { // CompareProps computes type specific property diffs func (sd *SpecAnalyser) CompareProps(type1, type2 *spec.SchemaProps) []TypeDiff { - diffs := []TypeDiff{} diffs = CheckToFromPrimitiveType(diffs, type1, type2) @@ -563,7 +572,7 @@ func (sd *SpecAnalyser) CompareProps(type1, type2 *spec.SchemaProps) []TypeDiff return diffs } - if !(isPrimitiveType(type1.Type) && isPrimitiveType(type2.Type)) { + if !isPrimitiveType(type1.Type) || !isPrimitiveType(type2.Type) { return diffs } @@ -592,7 +601,8 @@ func (sd *SpecAnalyser) CompareProps(type1, type2 *spec.SchemaProps) []TypeDiff func (sd *SpecAnalyser) compareParams(urlMethod URLMethod, location string, name string, param1, param2 spec.Parameter) { diffLocation := DifferenceLocation{URL: urlMethod.Path, Method: urlMethod.Method} - childLocation := diffLocation.AddNode(getNameOnlyDiffNode(strings.Title(location))) + childLocation := diffLocation.AddNode(getNameOnlyDiffNode(sd.titler.String(location))) + sd.titler.Reset() paramLocation := diffLocation.AddNode(getNameOnlyDiffNode(name)) sd.compareDescripton(paramLocation, param1.Description, param2.Description) @@ -629,7 +639,8 @@ func (sd *SpecAnalyser) addTypeDiff(location DifferenceLocation, diff *TypeDiff) sd.Diffs = sd.Diffs.addDiff(SpecDifference{ DifferenceLocation: location, Code: diffCopy.Change, - DiffInfo: desc}) + DiffInfo: desc, + }) } func (sd *SpecAnalyser) compareDescripton(location DifferenceLocation, desc1, desc2 string) { @@ -651,6 +662,7 @@ func isPrimitiveType(item spec.StringOrArray) bool { func isArrayType(item spec.StringOrArray) bool { return len(item) > 0 && item[0] == ArrayType } + func (sd *SpecAnalyser) getRefSchemaFromSpec1(ref spec.Ref) (*spec.Schema, string) { return sd.schemaFromRef(ref, &sd.Definitions1) } @@ -663,7 +675,6 @@ func (sd *SpecAnalyser) getRefSchemaFromSpec2(ref spec.Ref) (*spec.Schema, strin type CompareSchemaFn func(location DifferenceLocation, schema1, schema2 *spec.Schema) func (sd *SpecAnalyser) compareSchema(location DifferenceLocation, schema1, schema2 *spec.Schema) { - refDiffs := []TypeDiff{} refDiffs = CheckRefChange(refDiffs, schema1, schema2) if len(refDiffs) > 0 { @@ -826,7 +837,6 @@ func (sd *SpecAnalyser) schemaFromRef(ref spec.Ref, defns *spec.Definitions) (ac sd.ReferencedDefinitions[definitionName] = true actualSchema = &foundSchema return - } func schemaLocationKey(location DifferenceLocation) string { diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_difference.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_difference.go index 73e38ce4e..14ffcc4d5 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_difference.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/spec_difference.go @@ -46,7 +46,6 @@ func equalNodes(a, b *Node) bool { a.IsArray == b.IsArray && a.TypeName == b.TypeName && equalNodes(a.ChildNode, b.ChildNode) - } // BreakingChangeCount Calculates the breaking change count @@ -187,7 +186,7 @@ func (sd SpecDifferences) ReportAllDiffs(fmtJSON bool) (io.Reader, error, error) if fmtJSON { b, err := JSONMarshal(sd) if err != nil { - return nil, fmt.Errorf("couldn't print results: %v", err), nil + return nil, fmt.Errorf("couldn't print results: %w", err), nil } out, err := prettyprint(b) return out, err, nil diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/type_adapters.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/type_adapters.go index 5679367fd..c264395f8 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/type_adapters.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/diff/type_adapters.go @@ -11,8 +11,8 @@ func forItems(items *spec.Items) *spec.Schema { valids := items.CommonValidations schema := spec.Schema{ SchemaProps: spec.SchemaProps{ - Type: []string{items.SimpleSchema.Type}, - Format: items.SimpleSchema.Format, + Type: []string{items.Type}, + Format: items.Format, Maximum: valids.Maximum, ExclusiveMaximum: valids.ExclusiveMaximum, Minimum: valids.Minimum, diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/expand.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/expand.go index ed1fd3bfa..bef84c8be 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/expand.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/expand.go @@ -4,13 +4,15 @@ import ( "encoding/json" "errors" "fmt" + "io" "log" "os" + flags "github.com/jessevdk/go-flags" + "github.com/go-openapi/loads" "github.com/go-openapi/spec" "github.com/go-openapi/swag" - flags "github.com/jessevdk/go-flags" ) // ExpandSpec is a command that expands the $refs in a swagger document. @@ -42,6 +44,8 @@ func (c *ExpandSpec) Execute(args []string) error { return writeToFile(exp.Spec(), !c.Compact, c.Format, string(c.Output)) } +var defaultWriter io.Writer = os.Stdout + func writeToFile(swspec *spec.Swagger, pretty bool, format string, output string) error { var b []byte var err error @@ -61,7 +65,7 @@ func writeToFile(swspec *spec.Swagger, pretty bool, format string, output string if erg := json.Unmarshal(b, &data); erg != nil { log.Fatalln(erg) } - var bb interface{} + var bb any bb, err = data.MarshalYAML() if err == nil { b = bb.([]byte) @@ -73,10 +77,11 @@ func writeToFile(swspec *spec.Swagger, pretty bool, format string, output string return err } - if output == "" { - fmt.Println(string(b)) - return nil + switch output { + case "", "-": + _, e := fmt.Fprintf(defaultWriter, "%s\n", b) + return e + default: + return os.WriteFile(output, b, 0o644) //#nosec } - - return os.WriteFile(output, b, 0644) // #nosec } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/flatten.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/flatten.go index b30b50fd5..0001971b9 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/flatten.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/flatten.go @@ -3,10 +3,12 @@ package commands import ( "errors" + flags "github.com/jessevdk/go-flags" + "github.com/go-openapi/analysis" "github.com/go-openapi/loads" + "github.com/go-swagger/go-swagger/cmd/swagger/commands/generate" - flags "github.com/jessevdk/go-flags" ) // FlattenSpec is a command that flattens a swagger document @@ -31,7 +33,7 @@ func (c *FlattenSpec) Execute(args []string) error { return err } - flattenOpts := c.FlattenCmdOptions.SetFlattenOptions(&analysis.FlattenOpts{ + flattenOpts := c.SetFlattenOptions(&analysis.FlattenOpts{ // defaults Minimal: true, Verbose: true, diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/cli.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/cli.go index e8ea11c79..7896536a7 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/cli.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/cli.go @@ -7,12 +7,13 @@ type Cli struct { Client // cmd/<cli-app-name>/main.go will be generated. This ensures that go install will compile the app with desired name. CliAppName string `long:"cli-app-name" description:"the app name for the cli executable. useful for go install." default:"cli"` + CliPackage string `long:"cli-package" description:"the package to save the cli specific code" default:"cli"` } func (c Cli) apply(opts *generator.GenOpts) { c.Client.apply(opts) opts.IncludeCLi = true - opts.CliPackage = "cli" // hardcoded for now, can be exposed via cmd opt later + opts.CliPackage = c.CliPackage opts.CliAppName = c.CliAppName } @@ -21,6 +22,6 @@ func (c *Cli) generate(opts *generator.GenOpts) error { } // Execute runs this command -func (c *Cli) Execute(args []string) error { +func (c *Cli) Execute(_ []string) error { return createSwagger(c) } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/client.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/client.go index 3a78b5622..728fcaa88 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/client.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/client.go @@ -67,20 +67,19 @@ func (c *Client) generate(opts *generator.GenOpts) error { return generator.GenerateClient(c.Name, c.Models.Models, c.Operations.Operations, opts) } -func (c *Client) log(rp string) { +func (c *Client) log(_ string) { log.Println(`Generation completed! For this generation to compile you need to have some packages in your go.mod: * github.com/go-openapi/errors * github.com/go-openapi/runtime - * github.com/go-openapi/runtime/client * github.com/go-openapi/strfmt You can get these now with: go mod tidy`) } // Execute runs this command -func (c *Client) Execute(args []string) error { +func (c *Client) Execute(_ []string) error { return createSwagger(c) } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/markdown.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/markdown.go index ba9df3812..0dd4fc962 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/markdown.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/markdown.go @@ -1,8 +1,9 @@ package generate import ( - "github.com/go-swagger/go-swagger/generator" "github.com/jessevdk/go-flags" + + "github.com/go-swagger/go-swagger/generator" ) // Markdown generates a markdown representation of the spec @@ -24,10 +25,10 @@ func (m *Markdown) generate(opts *generator.GenOpts) error { return generator.GenerateMarkdown(string(m.Output), m.Models.Models, m.Operations.Operations, opts) } -func (m Markdown) log(rp string) { +func (m Markdown) log(_ string) { } // Execute runs this command -func (m *Markdown) Execute(args []string) error { +func (m *Markdown) Execute(_ []string) error { return createSwagger(m) } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/model.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/model.go index 5dffa66ea..62b46b1f0 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/model.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/model.go @@ -71,7 +71,7 @@ func (m Model) apply(opts *generator.GenOpts) { opts.AcceptDefinitionsOnly = m.AcceptDefinitionsOnly } -func (m Model) log(rp string) { +func (m Model) log(_ string) { log.Println(`Generation completed! For this generation to compile you need to have some packages in your go.mod: @@ -87,8 +87,7 @@ func (m *Model) generate(opts *generator.GenOpts) error { } // Execute generates a model file -func (m *Model) Execute(args []string) error { - +func (m *Model) Execute(_ []string) error { if m.Shared.DumpData && len(append(m.Name, m.Models.Models...)) > 1 { return errors.New("only 1 model at a time is supported for dumping data") } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/operation.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/operation.go index ba554314a..9eea866ee 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/operation.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/operation.go @@ -83,8 +83,7 @@ func (o *Operation) generate(opts *generator.GenOpts) error { return generator.GenerateServerOperation(append(o.Name, o.Operations.Operations...), opts) } -func (o Operation) log(rp string) { - +func (o Operation) log(_ string) { log.Println(`Generation completed! For this generation to compile you need to have some packages in your go.mod: @@ -95,7 +94,7 @@ You can get these now with: go mod tidy`) } // Execute generates a model file -func (o *Operation) Execute(args []string) error { +func (o *Operation) Execute(_ []string) error { if o.Shared.DumpData && len(append(o.Name, o.Operations.Operations...)) > 1 { return errors.New("only 1 operation at a time is supported for dumping data") } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/server.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/server.go index 92495adde..2a5a6425b 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/server.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/server.go @@ -57,9 +57,10 @@ type Server struct { WithContext bool `long:"with-context" description:"handlers get a context as first arg (deprecated)"` } -func (s Server) apply(opts *generator.GenOpts) { +func (s *Server) apply(opts *generator.GenOpts) { if s.WithContext { log.Printf("warning: deprecated option --with-context is ignored") + s.WithContext = false } s.Shared.apply(opts) @@ -92,7 +93,7 @@ func (s *Server) generate(opts *generator.GenOpts) error { return generator.GenerateServer(s.Name, s.Models.Models, s.Operations.Operations, opts) } -func (s Server) log(rp string) { +func (s Server) log(_ string) { var flagsPackage string switch { case strings.HasPrefix(s.FlagStrategy, "pflag"): @@ -114,6 +115,6 @@ You can get these now with: go mod tidy`) } // Execute runs this command -func (s *Server) Execute(args []string) error { +func (s *Server) Execute(_ []string) error { return createSwagger(s) } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/shared.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/shared.go index 7eb3af3fa..b8a5f358c 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/shared.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/shared.go @@ -7,11 +7,13 @@ import ( "path/filepath" "strings" + flags "github.com/jessevdk/go-flags" + "github.com/spf13/viper" + "github.com/go-openapi/analysis" "github.com/go-openapi/swag" + "github.com/go-swagger/go-swagger/generator" - flags "github.com/jessevdk/go-flags" - "github.com/spf13/viper" ) // FlattenCmdOptions determines options to the flatten spec preprocessing @@ -125,6 +127,7 @@ type sharedOptionsCommon struct { SkipValidation bool `long:"skip-validation" description:"skips validation of spec prior to generation" group:"shared"` DumpData bool `long:"dump-data" description:"when present dumps the json for the template generator instead of generating files" group:"shared"` StrictResponders bool `long:"strict-responders" description:"Use strict type for the handler return value"` + ReturnErrors bool `long:"return-errors" short:"e" description:"handlers explicitly return an error as the second value" group:"shared"` FlattenCmdOptions } @@ -136,9 +139,10 @@ func (s sharedOptionsCommon) apply(opts *generator.GenOpts) { opts.AllowTemplateOverride = s.AllowTemplateOverride opts.ValidateSpec = !s.SkipValidation opts.DumpData = s.DumpData - opts.FlattenOpts = s.FlattenCmdOptions.SetFlattenOptions(opts.FlattenOpts) + opts.FlattenOpts = s.SetFlattenOptions(opts.FlattenOpts) opts.Copyright = string(s.CopyrightFile) opts.StrictResponders = s.StrictResponders + opts.ReturnErrors = s.ReturnErrors swag.AddInitialisms(s.AdditionalInitialisms...) } @@ -167,7 +171,7 @@ func createSwagger(s sharedCommand) error { opts.Copyright, err = setCopyright(opts.Copyright) if err != nil { - return fmt.Errorf("could not load copyright file: %v", err) + return fmt.Errorf("could not load copyright file: %w", err) } if opts.Template != "" { diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/sharedopts_nonwin.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/sharedopts_nonwin.go index 7f7c25187..630e20d90 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/sharedopts_nonwin.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/sharedopts_nonwin.go @@ -4,8 +4,9 @@ package generate import ( - "github.com/go-swagger/go-swagger/generator" "github.com/jessevdk/go-flags" + + "github.com/go-swagger/go-swagger/generator" ) type sharedOptions struct { diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/spec.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/spec.go index 58f6a945b..3f9c37126 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/spec.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/spec.go @@ -17,15 +17,17 @@ package generate import ( "encoding/json" "fmt" + "io" "os" "strings" "github.com/go-swagger/go-swagger/codescan" - "github.com/go-openapi/loads" - "github.com/go-openapi/spec" "github.com/jessevdk/go-flags" "gopkg.in/yaml.v3" + + "github.com/go-openapi/loads" + "github.com/go-openapi/spec" ) // SpecFile command to generate a swagger spec from a go application @@ -42,6 +44,7 @@ type SpecFile struct { ExcludeTags []string `long:"exclude-tag" short:"" description:"exclude routes having specified tags (can be specified many times)"` ExcludeDeps bool `long:"exclude-deps" short:"" description:"exclude all dependencies of project"` SetXNullableForPointers bool `long:"nullable-pointers" short:"n" description:"set x-nullable extension to true automatically for fields of pointer types without 'omitempty'"` + RefAliases bool `long:"ref-aliases" short:"r" description:"transform aliased types into $ref rather than expanding their definition"` } // Execute runs this command @@ -67,6 +70,7 @@ func (s *SpecFile) Execute(args []string) error { opts.ExcludeTags = s.ExcludeTags opts.ExcludeDeps = s.ExcludeDeps opts.SetXNullableForPointers = s.SetXNullableForPointers + opts.RefAliases = s.RefAliases swspec, err := codescan.Run(&opts) if err != nil { return err @@ -89,6 +93,8 @@ func loadSpec(input string) (*spec.Swagger, error) { return nil, nil } +var defaultWriter io.Writer = os.Stdout + func writeToFile(swspec *spec.Swagger, pretty bool, output string) error { var b []byte var err error @@ -103,11 +109,15 @@ func writeToFile(swspec *spec.Swagger, pretty bool, output string) error { return err } - if output == "" { - fmt.Println(string(b)) - return nil + switch output { + case "", "-": + _, e := fmt.Fprintf(defaultWriter, "%s\n", b) + return e + default: + return os.WriteFile(output, b, 0o644) //#nosec } - return os.WriteFile(output, b, 0644) // #nosec + + // #nosec } func marshalToJSONFormat(swspec *spec.Swagger, pretty bool) ([]byte, error) { @@ -123,7 +133,7 @@ func marshalToYAMLFormat(swspec *spec.Swagger) ([]byte, error) { return nil, err } - var jsonObj interface{} + var jsonObj any if err := yaml.Unmarshal(b, &jsonObj); err != nil { return nil, err } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/support.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/support.go index 9e52f428c..4e84c0267 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/support.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/generate/support.go @@ -48,20 +48,19 @@ func (s *Support) generate(opts *generator.GenOpts) error { return generator.GenerateSupport(s.Name, s.Models.Models, s.Operations.Operations, opts) } -func (s Support) log(rp string) { - +func (s Support) log(_ string) { log.Println(`Generation completed! For this generation to compile you need to have some packages in go.mod: * github.com/go-openapi/runtime - * github.com/asaskevich/govalidator + * github.com/go-openapi/strfmt * github.com/jessevdk/go-flags You can get these now with: go mod tidy`) } // Execute generates the supporting files file -func (s *Support) Execute(args []string) error { +func (s *Support) Execute(_ []string) error { return createSwagger(s) } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd.go index 7a992f2b7..5f6b05297 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd.go @@ -8,6 +8,6 @@ type InitCmd struct { } // Execute provides default empty implementation -func (i *InitCmd) Execute(args []string) error { +func (i *InitCmd) Execute(_ []string) error { return nil } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd/spec.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd/spec.go index c540dc5b4..b81eb933c 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd/spec.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/initcmd/spec.go @@ -15,7 +15,7 @@ import ( // Spec a command struct for initializing a new swagger application. type Spec struct { - Format string `long:"format" description:"the format for the spec document" default:"yaml" choice:"yaml" choice:"json"` + Format string `long:"format" description:"the format for the spec document" default:"yaml" choice:"yaml" choice:"json"` //nolint:staticcheck Title string `long:"title" description:"the title of the API"` Description string `long:"description" description:"the description of the API"` Version string `long:"version" description:"the version of the API" default:"0.1.0"` diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/mixin.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/mixin.go index 79e26c440..86db148b2 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/mixin.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/mixin.go @@ -6,10 +6,11 @@ import ( "log" "os" + flags "github.com/jessevdk/go-flags" + "github.com/go-openapi/analysis" "github.com/go-openapi/loads" "github.com/go-openapi/spec" - flags "github.com/jessevdk/go-flags" "github.com/go-swagger/go-swagger/generator" ) @@ -50,7 +51,6 @@ type MixinSpec struct { // generation tools that natively support hosting multiple specs in // one server process will not need this tool. func (c *MixinSpec) Execute(args []string) error { - if len(args) < 2 { return errors.New(nothingToDo) } @@ -90,8 +90,7 @@ func (c *MixinSpec) Execute(args []string) error { // with mixins to the given writer in JSON. Returns the warning // messages for collisions that occurred during mixin process and any // error. -func (c *MixinSpec) MixinFiles(primaryFile string, mixinFiles []string, w io.Writer) ([]string, error) { - +func (c *MixinSpec) MixinFiles(primaryFile string, mixinFiles []string, _ io.Writer) ([]string, error) { primaryDoc, err := loads.Spec(primaryFile) if err != nil { return nil, err diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/serve.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/serve.go index 63705f618..30ff8eed0 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/serve.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/serve.go @@ -10,12 +10,13 @@ import ( "path" "strconv" + "github.com/gorilla/handlers" + "github.com/toqueteos/webbrowser" + "github.com/go-openapi/loads" "github.com/go-openapi/runtime/middleware" "github.com/go-openapi/spec" "github.com/go-openapi/swag" - "github.com/gorilla/handlers" - "github.com/toqueteos/webbrowser" ) // ServeCmd to serve a swagger spec with docs ui @@ -48,7 +49,6 @@ func (s *ServeCmd) Execute(args []string) error { ContinueOnError: true, AbsoluteCircularRef: true, }) - if err != nil { return err } diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/version.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/version.go index 9a860653b..fd776066b 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/version.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/commands/version.go @@ -13,11 +13,10 @@ var ( ) // PrintVersion the command -type PrintVersion struct { -} +type PrintVersion struct{} // Execute this command -func (p *PrintVersion) Execute(args []string) error { +func (p *PrintVersion) Execute(_ []string) error { if Version == "" { if info, available := debug.ReadBuildInfo(); available && info.Main.Version != "(devel)" { // built from source, with module (e.g. go get) diff --git a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go index dfc89ba2e..54cc23223 100644 --- a/vendor/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go +++ b/vendor/github.com/go-swagger/go-swagger/cmd/swagger/swagger.go @@ -19,8 +19,9 @@ import ( "log" "os" - "github.com/go-swagger/go-swagger/cmd/swagger/commands" flags "github.com/jessevdk/go-flags" + + "github.com/go-swagger/go-swagger/cmd/swagger/commands" ) var opts struct { @@ -130,7 +131,7 @@ It aims to represent the contract of your API with a language agnostic descripti log.SetOutput(io.Discard) } opts.LogFile = func(logfile string) { - f, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + f, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o666) if err != nil { log.Fatalf("cannot write to file %s: %v", logfile, err) } diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/application.go b/vendor/github.com/go-swagger/go-swagger/codescan/application.go index ebaa6261a..b086f918d 100644 --- a/vendor/github.com/go-swagger/go-swagger/codescan/application.go +++ b/vendor/github.com/go-swagger/go-swagger/codescan/application.go @@ -9,11 +9,10 @@ import ( "os" "strings" + "github.com/go-openapi/spec" "github.com/go-openapi/swag" "golang.org/x/tools/go/packages" - - "github.com/go-openapi/spec" ) const pkgLoadMode = packages.NeedName | packages.NeedFiles | packages.NeedImports | packages.NeedDeps | packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo @@ -53,6 +52,7 @@ type Options struct { IncludeTags []string ExcludeTags []string SetXNullableForPointers bool + RefAliases bool // aliases result in $ref, otherwise aliases are expanded } type scanCtx struct { @@ -93,9 +93,15 @@ func newScanCtx(opts *Options) (*scanCtx, error) { return nil, err } - app, err := newTypeIndex(pkgs, opts.ExcludeDeps, - sliceToSet(opts.IncludeTags), sliceToSet(opts.ExcludeTags), - opts.Include, opts.Exclude, opts.SetXNullableForPointers) + app, err := newTypeIndex(pkgs, + withExcludeDeps(opts.ExcludeDeps), + withIncludeTags(sliceToSet(opts.IncludeTags)), + withExcludeTags(sliceToSet(opts.ExcludeTags)), + withIncludePkgs(opts.Include), + withExcludePkgs(opts.Exclude), + withXNullableForPointers(opts.SetXNullableForPointers), + withRefAliases(opts.RefAliases), + ) if err != nil { return nil, err } @@ -109,6 +115,7 @@ func newScanCtx(opts *Options) (*scanCtx, error) { type entityDecl struct { Comments *ast.CommentGroup Type *types.Named + Alias *types.Alias // added to supplement Named, after go1.22 Ident *ast.Ident Spec *ast.TypeSpec File *ast.File @@ -118,6 +125,29 @@ type entityDecl struct { hasParameterAnnotation bool } +// Obj returns the type name for the declaration defining the named type or alias t. +func (d *entityDecl) Obj() *types.TypeName { + if d.Type != nil { + return d.Type.Obj() + } + if d.Alias != nil { + return d.Alias.Obj() + } + + panic("invalid entityDecl: Type and Alias are both nil") +} + +func (d *entityDecl) ObjType() types.Type { + if d.Type != nil { + return d.Type + } + if d.Alias != nil { + return d.Alias + } + + panic("invalid entityDecl: Type and Alias are both nil") +} + func (d *entityDecl) Names() (name, goName string) { goName = d.Ident.Name name = goName @@ -138,6 +168,7 @@ DECLS: } } } + return } @@ -259,11 +290,15 @@ func (s *scanCtx) FindDecl(pkgPath, name string) (*entityDecl, bool) { def, ok := pkg.TypesInfo.Defs[ts.Name] if !ok { debugLog("couldn't find type info for %s", ts.Name) + continue } + nt, isNamed := def.Type().(*types.Named) - if !isNamed { - debugLog("%s is not a named type but a %T", ts.Name, def.Type()) + at, isAliased := def.Type().(*types.Alias) + if !isNamed && !isAliased { + debugLog("%s is not a named or an aliased type but a %T", ts.Name, def.Type()) + continue } @@ -275,31 +310,36 @@ func (s *scanCtx) FindDecl(pkgPath, name string) (*entityDecl, bool) { decl := &entityDecl{ Comments: comments, Type: nt, + Alias: at, Ident: ts.Name, Spec: ts, File: file, Pkg: pkg, } + return decl, true } } } } } + return nil, false } func (s *scanCtx) FindModel(pkgPath, name string) (*entityDecl, bool) { for _, cand := range s.app.Models { - ct := cand.Type.Obj() + ct := cand.Obj() if ct.Name() == name && ct.Pkg().Path() == pkgPath { return cand, true } } + if decl, found := s.FindDecl(pkgPath, name); found { s.app.ExtraModels[decl.Ident] = decl return decl, true } + return nil, false } @@ -314,9 +354,12 @@ func (s *scanCtx) DeclForType(t types.Type) (*entityDecl, bool) { return s.DeclForType(tpe.Elem()) case *types.Named: return s.FindDecl(tpe.Obj().Pkg().Path(), tpe.Obj().Name()) + case *types.Alias: + return s.FindDecl(tpe.Obj().Pkg().Path(), tpe.Obj().Name()) default: - log.Printf("unknown type to find the package for [%T]: %s", t, t.String()) + log.Printf("WARNING: unknown type to find the package for [%T]: %s", t, t.String()) + return nil, false } } @@ -333,6 +376,9 @@ func (s *scanCtx) PkgForType(t types.Type) (*packages.Package, bool) { case *types.Named: v, ok := s.app.AllPackages[tpe.Obj().Pkg().Path()] return v, ok + case *types.Alias: + v, ok := s.app.AllPackages[tpe.Obj().Pkg().Path()] + return v, ok default: log.Printf("unknown type to find the package for [%T]: %s", t, t.String()) return nil, false @@ -385,7 +431,7 @@ func (s *scanCtx) FindEnumValues(pkg *packages.Package, enumName string) (list [ desc = &strings.Builder{} namesLen = len(vs.Names) ) - desc.WriteString(fmt.Sprintf("%v ", blValue)) + fmt.Fprintf(desc, "%v ", blValue) for i, name := range vs.Names { desc.WriteString(name.Name) if i < namesLen-1 { @@ -419,18 +465,60 @@ func (s *scanCtx) FindEnumValues(pkg *packages.Package, enumName string) (list [ return list, descList, true } -func newTypeIndex(pkgs []*packages.Package, excludeDeps bool, includeTags, excludeTags map[string]bool, includePkgs, excludePkgs []string, setXNullableForPointers bool) (*typeIndex, error) { +type typeIndexOption func(*typeIndex) + +func withExcludeDeps(excluded bool) typeIndexOption { + return func(a *typeIndex) { + a.excludeDeps = excluded + } +} + +func withIncludeTags(included map[string]bool) typeIndexOption { + return func(a *typeIndex) { + a.includeTags = included + } +} + +func withExcludeTags(excluded map[string]bool) typeIndexOption { + return func(a *typeIndex) { + a.excludeTags = excluded + } +} + +func withIncludePkgs(included []string) typeIndexOption { + return func(a *typeIndex) { + a.includePkgs = included + } +} + +func withExcludePkgs(excluded []string) typeIndexOption { + return func(a *typeIndex) { + a.excludePkgs = excluded + } +} + +func withXNullableForPointers(enabled bool) typeIndexOption { + return func(a *typeIndex) { + a.setXNullableForPointers = enabled + } +} + +func withRefAliases(enabled bool) typeIndexOption { + return func(a *typeIndex) { + a.refAliases = enabled + } +} + +func newTypeIndex(pkgs []*packages.Package, opts ...typeIndexOption) (*typeIndex, error) { ac := &typeIndex{ - AllPackages: make(map[string]*packages.Package), - Models: make(map[*ast.Ident]*entityDecl), - ExtraModels: make(map[*ast.Ident]*entityDecl), - excludeDeps: excludeDeps, - includeTags: includeTags, - excludeTags: excludeTags, - includePkgs: includePkgs, - excludePkgs: excludePkgs, - setXNullableForPointers: setXNullableForPointers, + AllPackages: make(map[string]*packages.Package), + Models: make(map[*ast.Ident]*entityDecl), + ExtraModels: make(map[*ast.Ident]*entityDecl), } + for _, apply := range opts { + apply(ac) + } + if err := ac.build(pkgs); err != nil { return nil, err } @@ -452,6 +540,7 @@ type typeIndex struct { includePkgs []string excludePkgs []string setXNullableForPointers bool + refAliases bool } func (a *typeIndex) build(pkgs []*packages.Package) error { @@ -554,8 +643,10 @@ func (a *typeIndex) processDecl(pkg *packages.Package, file *ast.File, n node, g continue } nt, isNamed := def.Type().(*types.Named) - if !isNamed { - debugLog("%s is not a named type but a %T", ts.Name, def.Type()) + at, isAliased := def.Type().(*types.Alias) + if !isNamed && !isAliased { + debugLog("%s is not a named or aliased type but a %T", ts.Name, def.Type()) + continue } @@ -567,20 +658,26 @@ func (a *typeIndex) processDecl(pkg *packages.Package, file *ast.File, n node, g decl := &entityDecl{ Comments: comments, Type: nt, + Alias: at, Ident: ts.Name, Spec: ts, File: file, Pkg: pkg, } key := ts.Name - if n&modelNode != 0 && decl.HasModelAnnotation() { + switch { + case n&modelNode != 0 && decl.HasModelAnnotation(): a.Models[key] = decl - } - if n¶metersNode != 0 && decl.HasParameterAnnotation() { + case n¶metersNode != 0 && decl.HasParameterAnnotation(): a.Parameters = append(a.Parameters, decl) - } - if n&responseNode != 0 && decl.HasResponseAnnotation() { + case n&responseNode != 0 && decl.HasResponseAnnotation(): a.Responses = append(a.Responses, decl) + default: + debugLog( + "type %q skipped because it is not tagged as a model, a parameter or a response. %s", + decl.Obj().Name(), + "It may reenter the scope because it is a discovered dependency", + ) } } } @@ -668,6 +765,6 @@ func (a *typeIndex) detectNodes(file *ast.File) (node, error) { func debugLog(format string, args ...interface{}) { if Debug { - log.Printf(format, args...) + _ = log.Output(2, fmt.Sprintf(format, args...)) } } diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/assertions.go b/vendor/github.com/go-swagger/go-swagger/codescan/assertions.go new file mode 100644 index 000000000..a6c8100d0 --- /dev/null +++ b/vendor/github.com/go-swagger/go-swagger/codescan/assertions.go @@ -0,0 +1,34 @@ +package codescan + +import ( + "fmt" + "go/types" +) + +type Error string + +func (e Error) Error() string { + return string(e) +} + +const ( + ErrInternal Error = "internal error due to a bug or a mishandling of go types AST. This usually indicates a bug in the scanner" +) + +// code assertions to be explicit about the various expectations when entering a function + +func mustNotBeABuiltinType(o *types.TypeName) { + if o.Pkg() != nil { + return + } + + panic(fmt.Errorf("type %q expected not to be a builtin: %w", o.Name(), ErrInternal)) +} + +func mustHaveRightHandSide(a *types.Alias) { + if a.Rhs() != nil { + return + } + + panic(fmt.Errorf("type alias %q expected to declare a right-hand-side: %w", a.Obj().Name(), ErrInternal)) +} diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/parameters.go b/vendor/github.com/go-swagger/go-swagger/codescan/parameters.go index 1ee769ae8..6a090bd37 100644 --- a/vendor/github.com/go-swagger/go-swagger/codescan/parameters.go +++ b/vendor/github.com/go-swagger/go-swagger/codescan/parameters.go @@ -15,6 +15,8 @@ type paramTypable struct { param *spec.Parameter } +func (pt paramTypable) In() string { return pt.param.In } + func (pt paramTypable) Level() int { return 0 } func (pt paramTypable) Typed(tpe, format string) { @@ -36,7 +38,7 @@ func (pt paramTypable) Items() swaggerTypable { pt.param.Items = new(spec.Items) } pt.param.Type = "array" - return itemsTypable{pt.param.Items, 1} + return itemsTypable{pt.param.Items, 1, pt.param.In} } func (pt paramTypable) Schema() *spec.Schema { @@ -71,8 +73,11 @@ func (pt paramTypable) WithEnumDescription(desc string) { type itemsTypable struct { items *spec.Items level int + in string } +func (pt itemsTypable) In() string { return pt.in } // TODO(fred): inherit from param + func (pt itemsTypable) Level() int { return pt.level } func (pt itemsTypable) Typed(tpe, format string) { @@ -92,7 +97,7 @@ func (pt itemsTypable) Items() swaggerTypable { pt.items.Items = new(spec.Items) } pt.items.Type = "array" - return itemsTypable{pt.items.Items, pt.level + 1} + return itemsTypable{pt.items.Items, pt.level + 1, pt.in} } func (pt itemsTypable) AddExtension(key string, value interface{}) { @@ -188,10 +193,11 @@ func (p *parameterBuilder) Build(operations map[string]*spec.Operation) error { // * has to document the validations that apply for the type and the field // * when the struct field points to a model it becomes a ref: #/definitions/ModelName // * comments that aren't tags is used as the description - if err := p.buildFromType(p.decl.Type, operation, make(map[string]spec.Parameter)); err != nil { + if err := p.buildFromType(p.decl.ObjType(), operation, make(map[string]spec.Parameter)); err != nil { return err } } + return nil } @@ -200,88 +206,247 @@ func (p *parameterBuilder) buildFromType(otpe types.Type, op *spec.Operation, se case *types.Pointer: return p.buildFromType(tpe.Elem(), op, seen) case *types.Named: - o := tpe.Obj() - switch stpe := o.Type().Underlying().(type) { - case *types.Struct: - debugLog("build from type %s: %T", tpe.Obj().Name(), otpe) - if decl, found := p.ctx.DeclForType(o.Type()); found { - return p.buildFromStruct(decl, stpe, op, seen) - } - return p.buildFromStruct(p.decl, stpe, op, seen) - default: - return fmt.Errorf("unhandled type (%T): %s", stpe, o.Type().Underlying().String()) - } + return p.buildNamedType(tpe, op, seen) + case *types.Alias: + debugLog("alias(parameters.buildFromType): got alias %v to %v", tpe, tpe.Rhs()) + return p.buildAlias(tpe, op, seen) default: return fmt.Errorf("unhandled type (%T): %s", otpe, tpe.String()) } } +func (p *parameterBuilder) buildNamedType(tpe *types.Named, op *spec.Operation, seen map[string]spec.Parameter) error { + o := tpe.Obj() + if isAny(o) || isStdError(o) { + return fmt.Errorf("%s type not supported in the context of a parameters section definition", o.Name()) + } + mustNotBeABuiltinType(o) + + switch stpe := o.Type().Underlying().(type) { + case *types.Struct: + debugLog("build from named type %s: %T", o.Name(), tpe) + if decl, found := p.ctx.DeclForType(o.Type()); found { + return p.buildFromStruct(decl, stpe, op, seen) + } + + return p.buildFromStruct(p.decl, stpe, op, seen) + default: + return fmt.Errorf("unhandled type (%T): %s", stpe, o.Type().Underlying().String()) + } +} + +func (p *parameterBuilder) buildAlias(tpe *types.Alias, op *spec.Operation, seen map[string]spec.Parameter) error { + o := tpe.Obj() + if isAny(o) || isStdError(o) { + return fmt.Errorf("%s type not supported in the context of a parameters section definition", o.Name()) + } + mustNotBeABuiltinType(o) + mustHaveRightHandSide(tpe) + + rhs := tpe.Rhs() + decl, ok := p.ctx.FindModel(o.Pkg().Path(), o.Name()) + if !ok { + return fmt.Errorf("can't find source file for aliased type: %v -> %v", tpe, rhs) + } + p.postDecls = append(p.postDecls, decl) // mark the left-hand side as discovered + + switch rtpe := rhs.(type) { + // load declaration for named unaliased type + case *types.Named: + o := rtpe.Obj() + if o.Pkg() == nil { + break // builtin + } + decl, found := p.ctx.FindModel(o.Pkg().Path(), o.Name()) + if !found { + return fmt.Errorf("can't find source file for target type of alias: %v -> %v", tpe, rtpe) + } + p.postDecls = append(p.postDecls, decl) + case *types.Alias: + o := rtpe.Obj() + if o.Pkg() == nil { + break // builtin + } + decl, found := p.ctx.FindModel(o.Pkg().Path(), o.Name()) + if !found { + return fmt.Errorf("can't find source file for target type of alias: %v -> %v", tpe, rtpe) + } + p.postDecls = append(p.postDecls, decl) + } + + return p.buildFromType(rhs, op, seen) +} + func (p *parameterBuilder) buildFromField(fld *types.Var, tpe types.Type, typable swaggerTypable, seen map[string]spec.Parameter) error { debugLog("build from field %s: %T", fld.Name(), tpe) + switch ftpe := tpe.(type) { case *types.Basic: return swaggerSchemaForType(ftpe.Name(), typable) case *types.Struct: - sb := schemaBuilder{ - decl: p.decl, - ctx: p.ctx, - } - if err := sb.buildFromType(tpe, typable); err != nil { - return err - } - p.postDecls = append(p.postDecls, sb.postDecls...) - return nil + return p.buildFromFieldStruct(ftpe, typable) case *types.Pointer: return p.buildFromField(fld, ftpe.Elem(), typable, seen) case *types.Interface: - sb := schemaBuilder{ - decl: p.decl, - ctx: p.ctx, - } - if err := sb.buildFromType(tpe, typable); err != nil { - return err - } - p.postDecls = append(p.postDecls, sb.postDecls...) - return nil + return p.buildFromFieldInterface(ftpe, typable) case *types.Array: return p.buildFromField(fld, ftpe.Elem(), typable.Items(), seen) case *types.Slice: return p.buildFromField(fld, ftpe.Elem(), typable.Items(), seen) case *types.Map: - schema := new(spec.Schema) - typable.Schema().Typed("object", "").AdditionalProperties = &spec.SchemaOrBool{ - Schema: schema, + return p.buildFromFieldMap(ftpe, typable) + case *types.Named: + return p.buildNamedField(ftpe, typable) + case *types.Alias: + debugLog("alias(parameters.buildFromField): got alias %v to %v", ftpe, ftpe.Rhs()) // TODO + return p.buildFieldAlias(ftpe, typable, fld, seen) + default: + return fmt.Errorf("unknown type for %s: %T", fld.String(), fld.Type()) + } +} + +func (p *parameterBuilder) buildFromFieldStruct(tpe *types.Struct, typable swaggerTypable) error { + sb := schemaBuilder{ + decl: p.decl, + ctx: p.ctx, + } + + if err := sb.buildFromType(tpe, typable); err != nil { + return err + } + p.postDecls = append(p.postDecls, sb.postDecls...) + + return nil +} + +func (p *parameterBuilder) buildFromFieldMap(ftpe *types.Map, typable swaggerTypable) error { + schema := new(spec.Schema) + typable.Schema().Typed("object", "").AdditionalProperties = &spec.SchemaOrBool{ + Schema: schema, + } + + sb := schemaBuilder{ + decl: p.decl, + ctx: p.ctx, + } + + if err := sb.buildFromType(ftpe.Elem(), schemaTypable{schema, typable.Level() + 1}); err != nil { + return err + } + + return nil +} + +func (p *parameterBuilder) buildFromFieldInterface(tpe *types.Interface, typable swaggerTypable) error { + sb := schemaBuilder{ + decl: p.decl, + ctx: p.ctx, + } + + if err := sb.buildFromType(tpe, typable); err != nil { + return err + } + + p.postDecls = append(p.postDecls, sb.postDecls...) + + return nil +} + +func (p *parameterBuilder) buildNamedField(ftpe *types.Named, typable swaggerTypable) error { + o := ftpe.Obj() + if isAny(o) { + // e.g. Field interface{} or Field any + return nil + } + if isStdError(o) { + return fmt.Errorf("%s type not supported in the context of a parameter definition", o.Name()) + } + mustNotBeABuiltinType(o) + + decl, found := p.ctx.DeclForType(o.Type()) + if !found { + return fmt.Errorf("unable to find package and source file for: %s", ftpe.String()) + } + + if isStdTime(o) { + typable.Typed("string", "date-time") + return nil + } + + if sfnm, isf := strfmtName(decl.Comments); isf { + typable.Typed("string", sfnm) + return nil + } + + sb := &schemaBuilder{ctx: p.ctx, decl: decl} + sb.inferNames() + if err := sb.buildFromType(decl.ObjType(), typable); err != nil { + return err + } + + p.postDecls = append(p.postDecls, sb.postDecls...) + + return nil +} + +func (p *parameterBuilder) buildFieldAlias(tpe *types.Alias, typable swaggerTypable, fld *types.Var, seen map[string]spec.Parameter) error { + o := tpe.Obj() + if isAny(o) { + // e.g. Field interface{} or Field any + _ = typable.Schema() + + return nil // just leave an empty schema + } + if isStdError(o) { + return fmt.Errorf("%s type not supported in the context of a parameter definition", o.Name()) + } + mustNotBeABuiltinType(o) + mustHaveRightHandSide(tpe) + + rhs := tpe.Rhs() + decl, ok := p.ctx.FindModel(o.Pkg().Path(), o.Name()) + if !ok { + return fmt.Errorf("can't find source file for aliased type: %v -> %v", tpe, rhs) + } + p.postDecls = append(p.postDecls, decl) // mark the left-hand side as discovered + + if typable.In() != "body" || !p.ctx.app.refAliases { + // if ref option is disabled, and always for non-body parameters: just expand the alias + unaliased := types.Unalias(tpe) + return p.buildFromField(fld, unaliased, typable, seen) + } + + // for parameters that are full-fledged schemas, consider expanding or ref'ing + switch rtpe := rhs.(type) { + // load declaration for named RHS type (might be an alias itself) + case *types.Named: + o := rtpe.Obj() + if o.Pkg() == nil { + break // builtin } - sb := schemaBuilder{ - decl: p.decl, - ctx: p.ctx, + + decl, found := p.ctx.FindModel(o.Pkg().Path(), o.Name()) + if !found { + return fmt.Errorf("can't find source file for target type of alias: %v -> %v", tpe, rtpe) } - if err := sb.buildFromType(ftpe.Elem(), schemaTypable{schema, typable.Level() + 1}); err != nil { - return err + + return p.makeRef(decl, typable) + case *types.Alias: + o := rtpe.Obj() + if o.Pkg() == nil { + break // builtin } - return nil - case *types.Named: - if decl, found := p.ctx.DeclForType(ftpe.Obj().Type()); found { - if decl.Type.Obj().Pkg().Path() == "time" && decl.Type.Obj().Name() == "Time" { - typable.Typed("string", "date-time") - return nil - } - if sfnm, isf := strfmtName(decl.Comments); isf { - typable.Typed("string", sfnm) - return nil - } - sb := &schemaBuilder{ctx: p.ctx, decl: decl} - sb.inferNames() - if err := sb.buildFromType(decl.Type, typable); err != nil { - return err - } - p.postDecls = append(p.postDecls, sb.postDecls...) - return nil + + decl, found := p.ctx.FindModel(o.Pkg().Path(), o.Name()) + if !found { + return fmt.Errorf("can't find source file for target type of alias: %v -> %v", tpe, rtpe) } - return fmt.Errorf("unable to find package and source file for: %s", ftpe.String()) - default: - return fmt.Errorf("unknown type for %s: %T", fld.String(), fld.Type()) + + return p.makeRef(decl, typable) } + + // anonymous type: just expand it + return p.buildFromField(fld, rhs, typable, seen) } func spExtensionsSetter(ps *spec.Parameter) func(*spec.Extensions) { @@ -515,3 +680,16 @@ func (p *parameterBuilder) buildFromStruct(decl *entityDecl, tpe *types.Struct, } return nil } + +func (p *parameterBuilder) makeRef(decl *entityDecl, prop swaggerTypable) error { + nm, _ := decl.Names() + ref, err := spec.NewRef("#/definitions/" + nm) + if err != nil { + return err + } + + prop.SetRef(ref) + p.postDecls = append(p.postDecls, decl) // mark the $ref target as discovered + + return nil +} diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/parser.go b/vendor/github.com/go-swagger/go-swagger/codescan/parser.go index 3733d50df..3582ad7e7 100644 --- a/vendor/github.com/go-swagger/go-swagger/codescan/parser.go +++ b/vendor/github.com/go-swagger/go-swagger/codescan/parser.go @@ -5,15 +5,17 @@ import ( "errors" "fmt" "go/ast" + "go/types" "log" "reflect" "regexp" "strconv" "strings" + "gopkg.in/yaml.v3" + "github.com/go-openapi/loads/fmts" "github.com/go-openapi/spec" - "gopkg.in/yaml.v3" ) func shouldAcceptTag(tags []string, includeTags map[string]bool, excludeTags map[string]bool) bool { @@ -204,6 +206,7 @@ type swaggerTypable interface { AddExtension(key string, value interface{}) WithEnum(...interface{}) WithEnumDescription(desc string) + In() string } // Map all Go builtin types that have Json representation to Swagger/Json types. @@ -695,11 +698,11 @@ func (sm *setMaximum) Parse(lines []string) error { } matches := sm.rx.FindStringSubmatch(lines[0]) if len(matches) > 2 && len(matches[2]) > 0 { - max, err := strconv.ParseFloat(matches[2], 64) + maximum, err := strconv.ParseFloat(matches[2], 64) if err != nil { return err } - sm.builder.SetMaximum(max, matches[1] == "<") + sm.builder.SetMaximum(maximum, matches[1] == "<") } return nil } @@ -723,11 +726,11 @@ func (sm *setMinimum) Parse(lines []string) error { } matches := sm.rx.FindStringSubmatch(lines[0]) if len(matches) > 2 && len(matches[2]) > 0 { - min, err := strconv.ParseFloat(matches[2], 64) + minimum, err := strconv.ParseFloat(matches[2], 64) if err != nil { return err } - sm.builder.SetMinimum(min, matches[1] == ">") + sm.builder.SetMinimum(minimum, matches[1] == ">") } return nil } @@ -1685,8 +1688,8 @@ func (ss *setOpExtensions) Parse(lines []string) error { exts.AddExtension(ext.Extension, ext.Root.(map[string]string)[ext.Extension]) } else if _, ok := ext.Root.(map[string]*[]string); ok { exts.AddExtension(ext.Extension, *(ext.Root.(map[string]*[]string)[ext.Extension])) - } else if _, ok := ext.Root.(map[string]interface{}); ok { - exts.AddExtension(ext.Extension, ext.Root.(map[string]interface{})[ext.Extension]) + } else if _, ok := ext.Root.(map[string]any); ok { + exts.AddExtension(ext.Extension, ext.Root.(map[string]any)[ext.Extension]) } else { debugLog("Unknown Extension type: %s", fmt.Sprint(reflect.TypeOf(ext.Root))) } @@ -1695,3 +1698,60 @@ func (ss *setOpExtensions) Parse(lines []string) error { ss.set(&exts.Extensions) return nil } + +var unsupportedTypes = map[string]struct{}{ + "complex64": {}, + "complex128": {}, +} + +type objecter interface { + Obj() *types.TypeName +} + +func unsupportedBuiltinType(tpe types.Type) bool { + unaliased := types.Unalias(tpe) + + switch ftpe := unaliased.(type) { + case *types.Basic: + return unsupportedBasic(ftpe) + case *types.TypeParam: + return true + case *types.Chan: + return true + case *types.Signature: + return true + case objecter: + return unsupportedBuiltin(ftpe) + default: + return false + } +} + +func unsupportedBuiltin(tpe objecter) bool { + o := tpe.Obj() + if o == nil { + return false + } + + if o.Pkg() != nil { + if o.Pkg().Path() == "unsafe" { + return true + } + + return false // not a builtin type + } + + _, found := unsupportedTypes[o.Name()] + + return found +} + +func unsupportedBasic(tpe *types.Basic) bool { + if tpe.Kind() == types.UnsafePointer { + return true + } + + _, found := unsupportedTypes[tpe.Name()] + + return found +} diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/responses.go b/vendor/github.com/go-swagger/go-swagger/codescan/responses.go index 39274baf0..cf99b7474 100644 --- a/vendor/github.com/go-swagger/go-swagger/codescan/responses.go +++ b/vendor/github.com/go-swagger/go-swagger/codescan/responses.go @@ -7,8 +7,9 @@ import ( "go/types" "strings" - "github.com/go-openapi/spec" "golang.org/x/tools/go/ast/astutil" + + "github.com/go-openapi/spec" ) type responseTypable struct { @@ -17,6 +18,8 @@ type responseTypable struct { response *spec.Response } +func (ht responseTypable) In() string { return ht.in } + func (ht responseTypable) Level() int { return 0 } func (ht responseTypable) Typed(tpe, format string) { @@ -52,7 +55,7 @@ func (ht responseTypable) Items() swaggerTypable { ht.header.Items = new(spec.Items) } ht.header.Type = "array" - return itemsTypable{ht.header.Items, 1} + return itemsTypable{ht.header.Items, 1, "header"} } func (ht responseTypable) SetRef(ref spec.Ref) { @@ -171,7 +174,7 @@ func (r *responseBuilder) Build(responses map[string]spec.Response) error { // * has to document the validations that apply for the type and the field // * when the struct field points to a model it becomes a ref: #/definitions/ModelName // * comments that aren't tags is used as the description - if err := r.buildFromType(r.decl.Type, &response, make(map[string]bool)); err != nil { + if err := r.buildFromType(r.decl.ObjType(), &response, make(map[string]bool)); err != nil { return err } responses[name] = response @@ -180,52 +183,117 @@ func (r *responseBuilder) Build(responses map[string]spec.Response) error { func (r *responseBuilder) buildFromField(fld *types.Var, tpe types.Type, typable swaggerTypable, seen map[string]bool) error { debugLog("build from field %s: %T", fld.Name(), tpe) + switch ftpe := tpe.(type) { case *types.Basic: return swaggerSchemaForType(ftpe.Name(), typable) case *types.Struct: - sb := schemaBuilder{ - decl: r.decl, - ctx: r.ctx, - } - if err := sb.buildFromType(tpe, typable); err != nil { - return err - } - r.postDecls = append(r.postDecls, sb.postDecls...) - return nil + return r.buildFromFieldStruct(ftpe, typable) case *types.Pointer: return r.buildFromField(fld, ftpe.Elem(), typable, seen) case *types.Interface: - sb := schemaBuilder{ - decl: r.decl, - ctx: r.ctx, - } - if err := sb.buildFromType(tpe, typable); err != nil { - return err - } - r.postDecls = append(r.postDecls, sb.postDecls...) - return nil + return r.buildFromFieldInterface(ftpe, typable) case *types.Array: return r.buildFromField(fld, ftpe.Elem(), typable.Items(), seen) case *types.Slice: return r.buildFromField(fld, ftpe.Elem(), typable.Items(), seen) case *types.Map: - schema := new(spec.Schema) - typable.Schema().Typed("object", "").AdditionalProperties = &spec.SchemaOrBool{ - Schema: schema, - } - sb := schemaBuilder{ - decl: r.decl, - ctx: r.ctx, - } - if err := sb.buildFromType(ftpe.Elem(), schemaTypable{schema, typable.Level() + 1}); err != nil { - return err - } - r.postDecls = append(r.postDecls, sb.postDecls...) - return nil + return r.buildFromFieldMap(ftpe, typable) case *types.Named: - if decl, found := r.ctx.DeclForType(ftpe.Obj().Type()); found { - if decl.Type.Obj().Pkg().Path() == "time" && decl.Type.Obj().Name() == "Time" { + return r.buildNamedField(ftpe, typable) + case *types.Alias: + debugLog("alias(responses.buildFromField): got alias %v to %v", ftpe, ftpe.Rhs()) + return r.buildFieldAlias(ftpe, typable, fld, seen) + default: + return fmt.Errorf("unknown type for %s: %T", fld.String(), fld.Type()) + } +} + +func (r *responseBuilder) buildFromFieldStruct(ftpe *types.Struct, typable swaggerTypable) error { + sb := schemaBuilder{ + decl: r.decl, + ctx: r.ctx, + } + + if err := sb.buildFromType(ftpe, typable); err != nil { + return err + } + + r.postDecls = append(r.postDecls, sb.postDecls...) + + return nil +} + +func (r *responseBuilder) buildFromFieldMap(ftpe *types.Map, typable swaggerTypable) error { + schema := new(spec.Schema) + typable.Schema().Typed("object", "").AdditionalProperties = &spec.SchemaOrBool{ + Schema: schema, + } + + sb := schemaBuilder{ + decl: r.decl, + ctx: r.ctx, + } + + if err := sb.buildFromType(ftpe.Elem(), schemaTypable{schema, typable.Level() + 1}); err != nil { + return err + } + + r.postDecls = append(r.postDecls, sb.postDecls...) + + return nil +} + +func (r *responseBuilder) buildFromFieldInterface(tpe types.Type, typable swaggerTypable) error { + sb := schemaBuilder{ + decl: r.decl, + ctx: r.ctx, + } + if err := sb.buildFromType(tpe, typable); err != nil { + return err + } + r.postDecls = append(r.postDecls, sb.postDecls...) + + return nil +} + +func (r *responseBuilder) buildFromType(otpe types.Type, resp *spec.Response, seen map[string]bool) error { + switch tpe := otpe.(type) { + case *types.Pointer: + return r.buildFromType(tpe.Elem(), resp, seen) + case *types.Named: + return r.buildNamedType(tpe, resp, seen) + case *types.Alias: + debugLog("alias(responses.buildFromType): got alias %v to %v", tpe, tpe.Rhs()) + return r.buildAlias(tpe, resp, seen) + default: + return errors.New("anonymous types are currently not supported for responses") + } +} + +func (r *responseBuilder) buildNamedType(tpe *types.Named, resp *spec.Response, seen map[string]bool) error { + o := tpe.Obj() + if isAny(o) || isStdError(o) { + return fmt.Errorf("%s type not supported in the context of a responses section definition", o.Name()) + } + mustNotBeABuiltinType(o) + // ICI + + switch stpe := o.Type().Underlying().(type) { // TODO(fred): this is wrong without checking for aliases? + case *types.Struct: + debugLog("build from type %s: %T", o.Name(), tpe) + if decl, found := r.ctx.DeclForType(o.Type()); found { + return r.buildFromStruct(decl, stpe, resp, seen) + } + return r.buildFromStruct(r.decl, stpe, resp, seen) + + default: + if decl, found := r.ctx.DeclForType(o.Type()); found { + var schema spec.Schema + typable := schemaTypable{schema: &schema, level: 0} + + d := decl.Obj() + if isStdTime(d) { typable.Typed("string", "date-time") return nil } @@ -235,58 +303,111 @@ func (r *responseBuilder) buildFromField(fld *types.Var, tpe types.Type, typable } sb := &schemaBuilder{ctx: r.ctx, decl: decl} sb.inferNames() - if err := sb.buildFromType(decl.Type, typable); err != nil { + if err := sb.buildFromType(tpe.Underlying(), typable); err != nil { return err } + resp.WithSchema(&schema) r.postDecls = append(r.postDecls, sb.postDecls...) return nil } - return fmt.Errorf("unable to find package and source file for: %s", ftpe.String()) - default: - return fmt.Errorf("unknown type for %s: %T", fld.String(), fld.Type()) + return fmt.Errorf("responses can only be structs, did you mean for %s to be the response body?", tpe.String()) } } -func (r *responseBuilder) buildFromType(otpe types.Type, resp *spec.Response, seen map[string]bool) error { - switch tpe := otpe.(type) { - case *types.Pointer: - return r.buildFromType(tpe.Elem(), resp, seen) +func (r *responseBuilder) buildAlias(tpe *types.Alias, resp *spec.Response, seen map[string]bool) error { + // panic("yay") + o := tpe.Obj() + if isAny(o) || isStdError(o) { + // wrong: TODO(fred): see what object exactly we want to build here - figure out with specific tests + return fmt.Errorf("%s type not supported in the context of a responses section definition", o.Name()) + } + mustNotBeABuiltinType(o) + mustHaveRightHandSide(tpe) + + rhs := tpe.Rhs() + decl, ok := r.ctx.FindModel(o.Pkg().Path(), o.Name()) + if !ok { + return fmt.Errorf("can't find source file for aliased type: %v -> %v", tpe, rhs) + } + r.postDecls = append(r.postDecls, decl) // mark the left-hand side as discovered + + if !r.ctx.app.refAliases { + // expand alias + unaliased := types.Unalias(tpe) + return r.buildFromType(unaliased.Underlying(), resp, seen) + } + + switch rtpe := rhs.(type) { + // load declaration for named unaliased type case *types.Named: - o := tpe.Obj() - switch stpe := o.Type().Underlying().(type) { - case *types.Struct: - debugLog("build from type %s: %T", tpe.Obj().Name(), otpe) - if decl, found := r.ctx.DeclForType(o.Type()); found { - return r.buildFromStruct(decl, stpe, resp, seen) - } - return r.buildFromStruct(r.decl, stpe, resp, seen) - default: - if decl, found := r.ctx.DeclForType(o.Type()); found { - var schema spec.Schema - typable := schemaTypable{schema: &schema, level: 0} - - if decl.Type.Obj().Pkg().Path() == "time" && decl.Type.Obj().Name() == "Time" { - typable.Typed("string", "date-time") - return nil - } - if sfnm, isf := strfmtName(decl.Comments); isf { - typable.Typed("string", sfnm) - return nil - } - sb := &schemaBuilder{ctx: r.ctx, decl: decl} - sb.inferNames() - if err := sb.buildFromType(tpe.Underlying(), typable); err != nil { - return err - } - resp.WithSchema(&schema) - r.postDecls = append(r.postDecls, sb.postDecls...) - return nil - } - return fmt.Errorf("responses can only be structs, did you mean for %s to be the response body?", otpe.String()) + o := rtpe.Obj() + if o.Pkg() == nil { + break // builtin } - default: - return errors.New("anonymous types are currently not supported for responses") + + typable := schemaTypable{schema: &spec.Schema{}, level: 0} + return r.makeRef(decl, typable) + case *types.Alias: + o := rtpe.Obj() + if o.Pkg() == nil { + break // builtin + } + + typable := schemaTypable{schema: &spec.Schema{}, level: 0} + + return r.makeRef(decl, typable) } + + return r.buildFromType(rhs, resp, seen) +} + +func (r *responseBuilder) buildNamedField(ftpe *types.Named, typable swaggerTypable) error { + decl, found := r.ctx.DeclForType(ftpe.Obj().Type()) + if !found { + return fmt.Errorf("unable to find package and source file for: %s", ftpe.String()) + } + + d := decl.Obj() + if isStdTime(d) { + typable.Typed("string", "date-time") + return nil + } + + if sfnm, isf := strfmtName(decl.Comments); isf { + typable.Typed("string", sfnm) + return nil + } + + // ICI + sb := &schemaBuilder{ctx: r.ctx, decl: decl} + sb.inferNames() + if err := sb.buildFromType(decl.ObjType(), typable); err != nil { + return err + } + + r.postDecls = append(r.postDecls, sb.postDecls...) + + return nil +} + +func (r *responseBuilder) buildFieldAlias(tpe *types.Alias, typable swaggerTypable, fld *types.Var, seen map[string]bool) error { + _ = fld + _ = seen + o := tpe.Obj() + if isAny(o) { + // e.g. Field interface{} or Field any + _ = typable.Schema() + + return nil // just leave an empty schema + } + + decl, ok := r.ctx.FindModel(o.Pkg().Path(), o.Name()) + if !ok { + return fmt.Errorf("can't find source file for aliased type: %v", tpe) + } + r.postDecls = append(r.postDecls, decl) // mark the left-hand side as discovered + + return r.makeRef(decl, typable) } func (r *responseBuilder) buildFromStruct(decl *entityDecl, tpe *types.Struct, resp *spec.Response, seen map[string]bool) error { @@ -330,6 +451,7 @@ func (r *responseBuilder) buildFromStruct(decl *entityDecl, tpe *types.Struct, r // if the field is annotated with swagger:ignore, ignore it if ignored(afld.Doc) { + debugLog("field %v of type %v is deliberately ignored", fld, tpe) continue } @@ -362,8 +484,11 @@ func (r *responseBuilder) buildFromStruct(decl *entityDecl, tpe *types.Struct, r if afld.Doc != nil && fileParam(afld.Doc) { resp.Schema = &spec.Schema{} resp.Schema.Typed("file", "") - } else if err := r.buildFromField(fld, fld.Type(), responseTypable{in, &ps, resp}, seen); err != nil { - return err + } else { + debugLog("build response %v (%v) (not a file)", fld, fld.Type()) + if err := r.buildFromField(fld, fld.Type(), responseTypable{in, &ps, resp}, seen); err != nil { + return err + } } if strfmtName, ok := strfmtName(afld.Doc); ok { @@ -478,3 +603,16 @@ func (r *responseBuilder) buildFromStruct(decl *entityDecl, tpe *types.Struct, r } return nil } + +func (r *responseBuilder) makeRef(decl *entityDecl, prop swaggerTypable) error { + nm, _ := decl.Names() + ref, err := spec.NewRef("#/definitions/" + nm) + if err != nil { + return err + } + + prop.SetRef(ref) + r.postDecls = append(r.postDecls, decl) // mark the $ref target as discovered + + return nil +} diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/schema.go b/vendor/github.com/go-swagger/go-swagger/codescan/schema.go index 640ac0830..670b2ece1 100644 --- a/vendor/github.com/go-swagger/go-swagger/codescan/schema.go +++ b/vendor/github.com/go-swagger/go-swagger/codescan/schema.go @@ -31,6 +31,8 @@ type schemaTypable struct { level int } +func (st schemaTypable) In() string { return "body" } + func (st schemaTypable) Typed(tpe, format string) { st.schema.Typed(tpe, format) } @@ -170,7 +172,7 @@ func (s *schemaBuilder) buildFromDecl(_ *entityDecl, schema *spec.Schema) error sp.setTitle = func(lines []string) { schema.Title = joinDropLast(lines) } sp.setDescription = func(lines []string) { schema.Description = joinDropLast(lines) - enumDesc := getEnumDesc(schema.VendorExtensible.Extensions) + enumDesc := getEnumDesc(schema.Extensions) if enumDesc != "" { schema.Description += "\n" + enumDesc } @@ -184,60 +186,83 @@ func (s *schemaBuilder) buildFromDecl(_ *entityDecl, schema *spec.Schema) error return nil } - switch tpe := s.decl.Type.Obj().Type().(type) { + defer func() { + if schema.Ref.String() == "" { + // unless this is a $ref, we add traceability of the origin of this schema in source + if s.Name != s.GoName { + addExtension(&schema.VendorExtensible, "x-go-name", s.GoName) + } + addExtension(&schema.VendorExtensible, "x-go-package", s.decl.Obj().Pkg().Path()) + } + }() + + switch tpe := s.decl.ObjType().(type) { + // TODO(fredbi): we may safely remove all the cases here that are not Named or Alias case *types.Basic: debugLog("basic: %v", tpe.Name()) + return nil case *types.Struct: - if err := s.buildFromStruct(s.decl, tpe, schema, make(map[string]string)); err != nil { - return err - } + return s.buildFromStruct(s.decl, tpe, schema, make(map[string]string)) case *types.Interface: - if err := s.buildFromInterface(s.decl, tpe, schema, make(map[string]string)); err != nil { - return err - } + return s.buildFromInterface(s.decl, tpe, schema, make(map[string]string)) case *types.Array: debugLog("array: %v -> %v", s.decl.Ident.Name, tpe.Elem().String()) + return nil case *types.Slice: debugLog("slice: %v -> %v", s.decl.Ident.Name, tpe.Elem().String()) + return nil case *types.Map: debugLog("map: %v -> [%v]%v", s.decl.Ident.Name, tpe.Key().String(), tpe.Elem().String()) + return nil case *types.Named: - o := tpe.Obj() - if o != nil { - debugLog("got the named type object: %s.%s | isAlias: %t | exported: %t", o.Pkg().Path(), o.Name(), o.IsAlias(), o.Exported()) - if o.Pkg().Name() == "time" && o.Name() == "Time" { - schema.Typed("string", "date-time") - return nil - } + debugLog("named: %v", tpe) + return s.buildDeclNamed(tpe, schema) + case *types.Alias: + debugLog("alias: %v -> %v", tpe, tpe.Rhs()) + tgt := schemaTypable{schema, 0} - ps := schemaTypable{schema, 0} - for { - ti := s.decl.Pkg.TypesInfo.Types[s.decl.Spec.Type] - if ti.IsBuiltin() { - break - } - if ti.IsType() { - if err := s.buildFromType(ti.Type, ps); err != nil { - return err - } - break - } - } - } + return s.buildDeclAlias(tpe, tgt) + case *types.TypeParam: + log.Printf("WARNING: generic type parameters are not supported yet %[1]v (%[1]T). Skipped", tpe) + return nil + case *types.Chan: + log.Printf("WARNING: channels are not supported %[1]v (%[1]T). Skipped", tpe) + return nil + case *types.Signature: + log.Printf("WARNING: functions are not supported %[1]v (%[1]T). Skipped", tpe) + return nil default: - log.Printf("WARNING: Missing parser for a %T, skipping model: %s\n", tpe, s.Name) + log.Printf("WARNING: missing parser for type %T, skipping model: %s\n", tpe, s.Name) return nil } +} - if schema.Ref.String() == "" { - if s.Name != s.GoName { - addExtension(&schema.VendorExtensible, "x-go-name", s.GoName) - } - addExtension(&schema.VendorExtensible, "x-go-package", s.decl.Type.Obj().Pkg().Path()) +func (s *schemaBuilder) buildDeclNamed(tpe *types.Named, schema *spec.Schema) error { + if unsupportedBuiltin(tpe) { + log.Printf("WARNING: skipped unsupported builtin type: %v", tpe) + + return nil } - return nil + o := tpe.Obj() + + mustNotBeABuiltinType(o) + + debugLog("got the named type object: %s.%s | isAlias: %t | exported: %t", o.Pkg().Path(), o.Name(), o.IsAlias(), o.Exported()) + if isStdTime(o) { + schema.Typed("string", "date-time") + return nil + } + + ps := schemaTypable{schema, 0} + ti := s.decl.Pkg.TypesInfo.Types[s.decl.Spec.Type] + if !ti.IsType() { + return fmt.Errorf("declaration is not a type: %v", o) + } + + return s.buildFromType(ti.Type, ps) } +// buildFromTextMarshal renders a type that marshals as text as a string func (s *schemaBuilder) buildFromTextMarshal(tpe types.Type, tgt swaggerTypable) error { if typePtr, ok := tpe.(*types.Pointer); ok { return s.buildFromTextMarshal(typePtr.Elem(), tgt) @@ -250,7 +275,8 @@ func (s *schemaBuilder) buildFromTextMarshal(tpe types.Type, tgt swaggerTypable) } tio := typeNamed.Obj() - if tio.Pkg() == nil && tio.Name() == "error" { + if isStdError(tio) { + tgt.AddExtension("x-go-type", tio.Name()) return swaggerSchemaForType(tio.Name(), tgt) } @@ -264,17 +290,20 @@ func (s *schemaBuilder) buildFromTextMarshal(tpe types.Type, tgt swaggerTypable) if !found { // this must be a builtin - debugLog("skipping because package is nil: %s", tpe.String()) + debugLog("skipping because package is nil: %v", tpe) return nil } - if pkg.Name == "time" && tio.Name() == "Time" { + + if isStdTime(tio) { tgt.Typed("string", "date-time") return nil } - if pkg.PkgPath == "encoding/json" && tio.Name() == "RawMessage" { - tgt.Typed("object", "") + + if isStdJSONRawMessage(tio) { + tgt.Typed("object", "") // TODO: this should actually be any type return nil } + cmt, hasComments := s.ctx.FindComments(pkg, tio.Name()) if !hasComments { cmt = new(ast.CommentGroup) @@ -286,26 +315,26 @@ func (s *schemaBuilder) buildFromTextMarshal(tpe types.Type, tgt swaggerTypable) } tgt.Typed("string", "") + tgt.AddExtension("x-go-type", tio.Pkg().Path()+"."+tio.Name()) + return nil } func (s *schemaBuilder) buildFromType(tpe types.Type, tgt swaggerTypable) error { - pkg, err := importer.Default().Import("encoding") - if err != nil { - return nil - } - ifc := pkg.Scope().Lookup("TextMarshaler").Type().Underlying().(*types.Interface) - // check if the type implements encoding.TextMarshaler interface - isTextMarshaler := types.Implements(tpe, ifc) - if isTextMarshaler { + // if so, the type is rendered as a string. + debugLog("schema buildFromType %v (%T)", tpe, tpe) + + if isTextMarshaler(tpe) { return s.buildFromTextMarshal(tpe, tgt) } switch titpe := tpe.(type) { - case *types.Alias: - return nil // resolves panic case *types.Basic: + if unsupportedBuiltinType(titpe) { + log.Printf("WARNING: skipped unsupported builtin type: %v", tpe) + return nil + } return swaggerSchemaForType(titpe.String(), tgt) case *types.Pointer: return s.buildFromType(titpe.Elem(), tgt) @@ -314,167 +343,451 @@ func (s *schemaBuilder) buildFromType(tpe types.Type, tgt swaggerTypable) error case *types.Interface: return s.buildFromInterface(s.decl, titpe, tgt.Schema(), make(map[string]string)) case *types.Slice: + // anonymous slice return s.buildFromType(titpe.Elem(), tgt.Items()) case *types.Array: + // anonymous array return s.buildFromType(titpe.Elem(), tgt.Items()) case *types.Map: - // debugLog("map: %v -> [%v]%v", fld.Name(), ftpe.Key().String(), ftpe.Elem().String()) - // check if key is a string type, if not print a message - // and skip the map property. Only maps with string keys can go into additional properties - sch := tgt.Schema() - if sch == nil { - return errors.New("items doesn't support maps") - } - eleProp := schemaTypable{sch, tgt.Level()} - key := titpe.Key() - isTextMarshaler := types.Implements(key, ifc) - if key.Underlying().String() == "string" || isTextMarshaler { - return s.buildFromType(titpe.Elem(), eleProp.AdditionalProperties()) - } + return s.buildFromMap(titpe, tgt) case *types.Named: - tio := titpe.Obj() - if tio.Pkg() == nil && tio.Name() == "error" { - return swaggerSchemaForType(tio.Name(), tgt) - } - debugLog("named refined type %s.%s", tio.Pkg().Path(), tio.Name()) - pkg, found := s.ctx.PkgForType(tpe) - if !found { - // this must be a builtin - debugLog("skipping because package is nil: %s", tpe.String()) + // a named type, e.g. type X struct {} + return s.buildNamedType(titpe, tgt) + case *types.Alias: + // a named alias, e.g. type X = {RHS type}. + debugLog("alias(schema.buildFromType): got alias %v to %v", titpe, titpe.Rhs()) + return s.buildAlias(titpe, tgt) + case *types.TypeParam: + log.Printf("WARNING: generic type parameters are not supported yet %[1]v (%[1]T). Skipped", titpe) + return nil + case *types.Chan: + log.Printf("WARNING: channels are not supported %[1]v (%[1]T). Skipped", tpe) + return nil + case *types.Signature: + log.Printf("WARNING: functions are not supported %[1]v (%[1]T). Skipped", tpe) + return nil + default: + panic(fmt.Errorf("ERROR: can't determine refined type %[1]v (%[1]T): %w", titpe, ErrInternal)) + } +} + +func (s *schemaBuilder) buildNamedType(titpe *types.Named, tgt swaggerTypable) error { + tio := titpe.Obj() + if unsupportedBuiltin(titpe) { + log.Printf("WARNING: skipped unsupported builtin type: %v", titpe) + return nil + } + if isAny(tio) { + // e.g type X any or type X interface{} + _ = tgt.Schema() + + return nil + } + + // special case of the "error" interface. + if isStdError(tio) { + tgt.AddExtension("x-go-type", tio.Name()) + return swaggerSchemaForType(tio.Name(), tgt) + } + + // special case of the "time.Time" type + if isStdTime(tio) { + tgt.Typed("string", "date-time") + return nil + } + + // special case of the "json.RawMessage" type + if isStdJSONRawMessage(tio) { + tgt.Typed("object", "") // TODO: this should actually be any type + return nil + } + + pkg, found := s.ctx.PkgForType(titpe) + debugLog("named refined type %s.%s", pkg, tio.Name()) + if !found { + // this must be a builtin + // + // This could happen for example when using unsupported types such as complex64, complex128, uintptr, + // or type constraints such as comparable. + debugLog("skipping because package is nil (builtin type): %v", tio) + + return nil + } + + cmt, hasComments := s.ctx.FindComments(pkg, tio.Name()) + if !hasComments { + cmt = new(ast.CommentGroup) + } + + if typeName, ok := typeName(cmt); ok { + _ = swaggerSchemaForType(typeName, tgt) + + return nil + } + + if s.decl.Spec.Assign.IsValid() { + debugLog("found assignment: %s.%s", tio.Pkg().Path(), tio.Name()) + return s.buildFromType(titpe.Underlying(), tgt) + } + + if titpe.TypeArgs() != nil && titpe.TypeArgs().Len() > 0 { + return s.buildFromType(titpe.Underlying(), tgt) + } + + // invariant: the Underlying cannot be an alias or named type + switch utitpe := titpe.Underlying().(type) { + case *types.Struct: + debugLog("found struct: %s.%s", tio.Pkg().Path(), tio.Name()) + + decl, ok := s.ctx.FindModel(tio.Pkg().Path(), tio.Name()) + if !ok { + debugLog("could not find model in index: %s.%s", tio.Pkg().Path(), tio.Name()) return nil } - if pkg.Name == "time" && tio.Name() == "Time" { + + o := decl.Obj() + if isStdTime(o) { tgt.Typed("string", "date-time") return nil } - if pkg.PkgPath == "encoding/json" && tio.Name() == "RawMessage" { - tgt.Typed("object", "") + + if sfnm, isf := strfmtName(cmt); isf { + tgt.Typed("string", sfnm) return nil } - cmt, hasComments := s.ctx.FindComments(pkg, tio.Name()) - if !hasComments { - cmt = new(ast.CommentGroup) - } if typeName, ok := typeName(cmt); ok { _ = swaggerSchemaForType(typeName, tgt) return nil } - if s.decl.Spec.Assign.IsValid() { - return s.buildFromType(titpe.Underlying(), tgt) + return s.makeRef(decl, tgt) + case *types.Interface: + debugLog("found interface: %s.%s", tio.Pkg().Path(), tio.Name()) + + decl, found := s.ctx.FindModel(tio.Pkg().Path(), tio.Name()) + if !found { + return fmt.Errorf("can't find source file for type: %v", utitpe) } - if titpe.TypeArgs() != nil && titpe.TypeArgs().Len() > 0 { - return s.buildFromType(titpe.Underlying(), tgt) + return s.makeRef(decl, tgt) + case *types.Basic: + if unsupportedBuiltinType(utitpe) { + log.Printf("WARNING: skipped unsupported builtin type: %v", utitpe) + return nil } - switch utitpe := tpe.Underlying().(type) { - case *types.Struct: - if decl, ok := s.ctx.FindModel(tio.Pkg().Path(), tio.Name()); ok { - if decl.Type.Obj().Pkg().Path() == "time" && decl.Type.Obj().Name() == "Time" { - tgt.Typed("string", "date-time") - return nil - } - if sfnm, isf := strfmtName(cmt); isf { - tgt.Typed("string", sfnm) - return nil - } - if typeName, ok := typeName(cmt); ok { - _ = swaggerSchemaForType(typeName, tgt) - return nil - } + debugLog("found primitive type: %s.%s", tio.Pkg().Path(), tio.Name()) - return s.makeRef(decl, tgt) - } - case *types.Interface: - if decl, ok := s.ctx.FindModel(tio.Pkg().Path(), tio.Name()); ok { - return s.makeRef(decl, tgt) + if sfnm, isf := strfmtName(cmt); isf { + tgt.Typed("string", sfnm) + return nil + } + + if enumName, ok := enumName(cmt); ok { + enumValues, enumDesces, _ := s.ctx.FindEnumValues(pkg, enumName) + if len(enumValues) > 0 { + tgt.WithEnum(enumValues...) + enumTypeName := reflect.TypeOf(enumValues[0]).String() + _ = swaggerSchemaForType(enumTypeName, tgt) } - case *types.Basic: - if sfnm, isf := strfmtName(cmt); isf { - tgt.Typed("string", sfnm) - return nil + if len(enumDesces) > 0 { + tgt.WithEnumDescription(strings.Join(enumDesces, "\n")) } + return nil + } - if enumName, ok := enumName(cmt); ok { - enumValues, enumDesces, _ := s.ctx.FindEnumValues(pkg, enumName) - if len(enumValues) > 0 { - tgt.WithEnum(enumValues...) - enumTypeName := reflect.TypeOf(enumValues[0]).String() - _ = swaggerSchemaForType(enumTypeName, tgt) - } - if len(enumDesces) > 0 { - tgt.WithEnumDescription(strings.Join(enumDesces, "\n")) - } - return nil - } + if defaultName, ok := defaultName(cmt); ok { + debugLog("default name: %s", defaultName) + return nil + } - if defaultName, ok := defaultName(cmt); ok { - debugLog(defaultName) //nolint:govet + if typeName, ok := typeName(cmt); ok { + _ = swaggerSchemaForType(typeName, tgt) + return nil + + } + + if isAliasParam(tgt) || aliasParam(cmt) { + err := swaggerSchemaForType(utitpe.Name(), tgt) + if err == nil { return nil } + } - if typeName, ok := typeName(cmt); ok { - _ = swaggerSchemaForType(typeName, tgt) - return nil + if decl, ok := s.ctx.FindModel(tio.Pkg().Path(), tio.Name()); ok { + return s.makeRef(decl, tgt) + } - } + return swaggerSchemaForType(utitpe.String(), tgt) + case *types.Array: + debugLog("found array type: %s.%s", tio.Pkg().Path(), tio.Name()) - if isAliasParam(tgt) || aliasParam(cmt) { - err := swaggerSchemaForType(utitpe.Name(), tgt) - if err == nil { - return nil - } + if sfnm, isf := strfmtName(cmt); isf { + if sfnm == "byte" { + tgt.Typed("string", sfnm) + return nil } - if decl, ok := s.ctx.FindModel(tio.Pkg().Path(), tio.Name()); ok { - return s.makeRef(decl, tgt) + if sfnm == "bsonobjectid" { + tgt.Typed("string", sfnm) + return nil } - return swaggerSchemaForType(utitpe.String(), tgt) - case *types.Array: - if sfnm, isf := strfmtName(cmt); isf { - if sfnm == "byte" { - tgt.Typed("string", sfnm) - return nil - } - if sfnm == "bsonobjectid" { - tgt.Typed("string", sfnm) - return nil - } - tgt.Items().Typed("string", sfnm) + tgt.Items().Typed("string", sfnm) + return nil + } + if decl, ok := s.ctx.FindModel(tio.Pkg().Path(), tio.Name()); ok { + return s.makeRef(decl, tgt) + } + return s.buildFromType(utitpe.Elem(), tgt.Items()) + case *types.Slice: + debugLog("found slice type: %s.%s", tio.Pkg().Path(), tio.Name()) + + if sfnm, isf := strfmtName(cmt); isf { + if sfnm == "byte" { + tgt.Typed("string", sfnm) return nil } - if decl, ok := s.ctx.FindModel(tio.Pkg().Path(), tio.Name()); ok { - return s.makeRef(decl, tgt) + tgt.Items().Typed("string", sfnm) + return nil + } + if decl, ok := s.ctx.FindModel(tio.Pkg().Path(), tio.Name()); ok { + return s.makeRef(decl, tgt) + } + return s.buildFromType(utitpe.Elem(), tgt.Items()) + case *types.Map: + debugLog("found map type: %s.%s", tio.Pkg().Path(), tio.Name()) + + if decl, ok := s.ctx.FindModel(tio.Pkg().Path(), tio.Name()); ok { + return s.makeRef(decl, tgt) + } + return nil + case *types.TypeParam: + log.Printf("WARNING: generic type parameters are not supported yet %[1]v (%[1]T). Skipped", utitpe) + return nil + case *types.Chan: + log.Printf("WARNING: channels are not supported %[1]v (%[1]T). Skipped", utitpe) + return nil + case *types.Signature: + log.Printf("WARNING: functions are not supported %[1]v (%[1]T). Skipped", utitpe) + return nil + default: + log.Printf( + "WARNING: can't figure out object type for named type (%T): %v [alias: %t]", + titpe.Underlying(), titpe.Underlying(), titpe.Obj().IsAlias(), + ) + + return nil + } +} + +// buildDeclAlias builds a top-level alias declaration. +func (s *schemaBuilder) buildDeclAlias(tpe *types.Alias, tgt swaggerTypable) error { + if unsupportedBuiltinType(tpe) { + log.Printf("WARNING: skipped unsupported builtin type: %v", tpe) + return nil + } + + o := tpe.Obj() + if isAny(o) { + _ = tgt.Schema() // this is mutating tgt to create an empty schema + return nil + } + if isStdError(o) { + tgt.AddExtension("x-go-type", o.Name()) + return swaggerSchemaForType(o.Name(), tgt) + } + mustNotBeABuiltinType(o) + + if isStdTime(o) { + tgt.Typed("string", "date-time") + return nil + } + + mustHaveRightHandSide(tpe) + rhs := tpe.Rhs() + + decl, ok := s.ctx.FindModel(o.Pkg().Path(), o.Name()) + if !ok { + return fmt.Errorf("can't find source file for aliased type: %v -> %v", tpe, rhs) + } + + s.postDecls = append(s.postDecls, decl) // mark the left-hand side as discovered + + if !s.ctx.app.refAliases { + // expand alias + return s.buildFromType(tpe.Underlying(), tgt) + } + + // resolve alias to named type as $ref + switch rtpe := rhs.(type) { + // named declarations: we construct a $ref to the right-hand side target of the alias + case *types.Named: + ro := rtpe.Obj() + rdecl, found := s.ctx.FindModel(ro.Pkg().Path(), ro.Name()) + if !found { + return fmt.Errorf("can't find source file for target type of alias: %v -> %v", tpe, rtpe) + } + + return s.makeRef(rdecl, tgt) + case *types.Alias: + ro := rtpe.Obj() + if unsupportedBuiltin(rtpe) { + log.Printf("WARNING: skipped unsupported builtin type: %v", rtpe) + return nil + } + if isAny(ro) { + // e.g. type X = any + _ = tgt.Schema() // this is mutating tgt to create an empty schema + return nil + } + if isStdError(ro) { + // e.g. type X = error + tgt.AddExtension("x-go-type", o.Name()) + return swaggerSchemaForType(o.Name(), tgt) + } + mustNotBeABuiltinType(ro) // TODO(fred): there are a few other cases + + rdecl, found := s.ctx.FindModel(ro.Pkg().Path(), ro.Name()) + if !found { + return fmt.Errorf("can't find source file for target type of alias: %v -> %v", tpe, rtpe) + } + + return s.makeRef(rdecl, tgt) + } + + // alias to anonymous type + return s.buildFromType(rhs, tgt) +} + +func (s *schemaBuilder) buildAnonymousInterface(it *types.Interface, tgt swaggerTypable, decl *entityDecl) error { + tgt.Typed("object", "") + + for i := range it.NumExplicitMethods() { + fld := it.ExplicitMethod(i) + if !fld.Exported() { + continue + } + sig, isSignature := fld.Type().(*types.Signature) + if !isSignature { + continue + } + if sig.Params().Len() > 0 { + continue + } + if sig.Results() == nil || sig.Results().Len() != 1 { + continue + } + + var afld *ast.Field + ans, _ := astutil.PathEnclosingInterval(decl.File, fld.Pos(), fld.Pos()) + // debugLog("got %d nodes (exact: %t)", len(ans), isExact) + for _, an := range ans { + at, valid := an.(*ast.Field) + if !valid { + continue } - return s.buildFromType(utitpe.Elem(), tgt.Items()) - case *types.Slice: - if sfnm, isf := strfmtName(cmt); isf { - if sfnm == "byte" { - tgt.Typed("string", sfnm) - return nil + + debugLog("maybe interface field %s: %s(%T)", fld.Name(), fld.Type().String(), fld.Type()) + afld = at + break + } + + if afld == nil { + debugLog("can't find source associated with %s for %s", fld.String(), it.String()) + continue + } + + // if the field is annotated with swagger:ignore, ignore it + if ignored(afld.Doc) { + continue + } + + name := fld.Name() + if afld.Doc != nil { + for _, cmt := range afld.Doc.List { + for _, ln := range strings.Split(cmt.Text, "\n") { + matches := rxName.FindStringSubmatch(ln) + ml := len(matches) + if ml > 1 { + name = matches[ml-1] + } } - tgt.Items().Typed("string", sfnm) - return nil - } - if decl, ok := s.ctx.FindModel(tio.Pkg().Path(), tio.Name()); ok { - return s.makeRef(decl, tgt) - } - return s.buildFromType(utitpe.Elem(), tgt.Items()) - case *types.Map: - if decl, ok := s.ctx.FindModel(tio.Pkg().Path(), tio.Name()); ok { - return s.makeRef(decl, tgt) } - return nil + } - default: - log.Printf("WARNING: can't figure out object type for named type (%T): %v [alias: %t]", tpe.Underlying(), tpe.Underlying(), titpe.Obj().IsAlias()) + if tgt.Schema().Properties == nil { + tgt.Schema().Properties = make(map[string]spec.Schema) + } + ps := tgt.Schema().Properties[name] + if err := s.buildFromType(sig.Results().At(0).Type(), schemaTypable{&ps, 0}); err != nil { + return err + } + if sfName, isStrfmt := strfmtName(afld.Doc); isStrfmt { + ps.Typed("string", sfName) + ps.Ref = spec.Ref{} + ps.Items = nil + } - return nil + if err := s.createParser(name, tgt.Schema(), &ps, afld).Parse(afld.Doc); err != nil { + return err } - default: - panic(fmt.Sprintf("WARNING: can't determine refined type %s (%T)", titpe.String(), titpe)) + + if ps.Ref.String() == "" && name != fld.Name() { + ps.AddExtension("x-go-name", fld.Name()) + } + + if s.ctx.app.setXNullableForPointers { + if _, isPointer := fld.Type().(*types.Signature).Results().At(0).Type().(*types.Pointer); isPointer && (ps.Extensions == nil || (ps.Extensions["x-nullable"] == nil && ps.Extensions["x-isnullable"] == nil)) { + ps.AddExtension("x-nullable", true) + } + } + + // seen[name] = fld.Name() + tgt.Schema().Properties[name] = ps + } + + return nil +} + +// buildAlias builds a reference to an alias from another type. +func (s *schemaBuilder) buildAlias(tpe *types.Alias, tgt swaggerTypable) error { + if unsupportedBuiltinType(tpe) { + log.Printf("WARNING: skipped unsupported builtin type: %v", tpe) + + return nil + } + + o := tpe.Obj() + if isAny(o) { + _ = tgt.Schema() + return nil + } + mustNotBeABuiltinType(o) + + decl, ok := s.ctx.FindModel(o.Pkg().Path(), o.Name()) + if !ok { + return fmt.Errorf("can't find source file for aliased type: %v", tpe) + } + + return s.makeRef(decl, tgt) +} + +func (s *schemaBuilder) buildFromMap(titpe *types.Map, tgt swaggerTypable) error { + // check if key is a string type, or knows how to marshall to text. + // If not, print a message and skip the map property. + // + // Only maps with string keys can go into additional properties + + sch := tgt.Schema() + if sch == nil { + return errors.New("items doesn't support maps") + } + + eleProp := schemaTypable{sch, tgt.Level()} + key := titpe.Key() + if key.Underlying().String() == "string" || isTextMarshaler(key) { + return s.buildFromType(titpe.Elem(), eleProp.AdditionalProperties()) } return nil @@ -482,6 +795,7 @@ func (s *schemaBuilder) buildFromType(tpe types.Type, tgt swaggerTypable) error func (s *schemaBuilder) buildFromInterface(decl *entityDecl, it *types.Interface, schema *spec.Schema, seen map[string]string) error { if it.Empty() { + // return an empty schema for empty interfaces return nil } @@ -494,98 +808,91 @@ func (s *schemaBuilder) buildFromInterface(decl *entityDecl, it *types.Interface if specType, ok := decl.Spec.Type.(*ast.InterfaceType); ok { flist = make([]*ast.Field, it.NumEmbeddeds()+it.NumExplicitMethods()) copy(flist, specType.Methods.List) - // for i := range specType.Methods.List { - // flist[i] = specType.Methods.List[i] - // } } // First collect the embedded interfaces - // create refs when the embedded interface is decorated with an allOf annotation - for i := 0; i < it.NumEmbeddeds(); i++ { + // create refs when: + // + // 1. the embedded interface is decorated with an allOf annotation + // 2. the embedded interface is an alias + for i := range it.NumEmbeddeds() { fld := it.EmbeddedType(i) + debugLog("inspecting embedded type in interface: %v", fld) + var ( + fieldHasAllOf bool + err error + ) + + if tgt == nil { + tgt = &spec.Schema{} + } switch ftpe := fld.(type) { case *types.Named: + debugLog("embedded named type (buildInterface): %v", ftpe) o := ftpe.Obj() - var afld *ast.Field - for _, an := range flist { - if len(an.Names) != 0 { - continue - } - - tpp := decl.Pkg.TypesInfo.Types[an.Type] - if tpp.Type.String() != o.Type().String() { - continue - } - - // decl. - debugLog("maybe interface field %s: %s(%T)", o.Name(), o.Type().String(), o.Type()) - afld = an - break - } - - if afld == nil { - debugLog("can't find source associated with %s for %s", fld.String(), it.String()) + if isAny(o) || isStdError(o) { + // ignore bultin interfaces continue } - // if the field is annotated with swagger:ignore, ignore it - if ignored(afld.Doc) { - continue + if fieldHasAllOf, err = s.buildNamedInterface(ftpe, flist, decl, schema, seen); err != nil { + return err } - - if !allOfMember(afld.Doc) { - var newSch spec.Schema - if err := s.buildEmbedded(o.Type(), &newSch, seen); err != nil { - return err - } - schema.AllOf = append(schema.AllOf, newSch) - hasAllOf = true - continue + case *types.Interface: + debugLog("embedded anonymous interface type (buildInterface): %v", ftpe) // e.g. type X interface{ interface{Error() string}} + var aliasedSchema spec.Schema + ps := schemaTypable{schema: &aliasedSchema} + if err = s.buildAnonymousInterface(ftpe, ps, decl); err != nil { + return err } - hasAllOf = true - if tgt == nil { - tgt = &spec.Schema{} + if aliasedSchema.Ref.String() != "" || len(aliasedSchema.Properties) > 0 || len(aliasedSchema.AllOf) > 0 { + schema.AddToAllOf(aliasedSchema) + fieldHasAllOf = true } - var newSch spec.Schema - // when the embedded struct is annotated with swagger:allOf it will be used as allOf property - // otherwise the fields will just be included as normal properties - if err := s.buildAllOf(o.Type(), &newSch); err != nil { + case *types.Alias: + debugLog("embedded alias (buildInterface): %v -> %v", ftpe, ftpe.Rhs()) + var aliasedSchema spec.Schema + ps := schemaTypable{schema: &aliasedSchema} + if err = s.buildAlias(ftpe, ps); err != nil { return err } - if afld.Doc != nil { - for _, cmt := range afld.Doc.List { - for _, ln := range strings.Split(cmt.Text, "\n") { - matches := rxAllOf.FindStringSubmatch(ln) - ml := len(matches) - if ml > 1 { - mv := matches[ml-1] - if mv != "" { - schema.AddExtension("x-class", mv) - } - } - } - } - } - schema.AllOf = append(schema.AllOf, newSch) + if aliasedSchema.Ref.String() != "" || len(aliasedSchema.Properties) > 0 || len(aliasedSchema.AllOf) > 0 { + schema.AddToAllOf(aliasedSchema) + fieldHasAllOf = true + } + case *types.Union: // e.g. type X interface{ ~uint16 | ~float32 } + log.Printf("WARNING: union type constraints are not supported yet %[1]v (%[1]T). Skipped", ftpe) + case *types.TypeParam: + log.Printf("WARNING: generic type parameters are not supported yet %[1]v (%[1]T). Skipped", ftpe) + case *types.Chan: + log.Printf("WARNING: channels are not supported %[1]v (%[1]T). Skipped", ftpe) + case *types.Signature: + log.Printf("WARNING: functions are not supported %[1]v (%[1]T). Skipped", ftpe) default: - log.Printf("WARNING: can't figure out object type for allOf named type (%T): %v", ftpe, ftpe.Underlying()) + log.Printf( + "WARNING: can't figure out object type for allOf named type (%T): %v", + ftpe, ftpe.Underlying(), + ) } - debugLog("got embedded interface: %s {%T}", fld.String(), fld) + + debugLog("got embedded interface: %v {%T}, fieldHasAllOf: %t", fld, fld, fieldHasAllOf) + hasAllOf = hasAllOf || fieldHasAllOf } if tgt == nil { tgt = schema } + // We can finally build the actual schema for the struct if tgt.Properties == nil { tgt.Properties = make(map[string]spec.Schema) } tgt.Typed("object", "") - for i := 0; i < it.NumExplicitMethods(); i++ { + for i := range it.NumExplicitMethods() { fld := it.ExplicitMethod(i) if !fld.Exported() { continue @@ -671,17 +978,91 @@ func (s *schemaBuilder) buildFromInterface(decl *entityDecl, it *types.Interface if hasAllOf && len(tgt.Properties) > 0 { schema.AllOf = append(schema.AllOf, *tgt) } + for k := range tgt.Properties { if _, ok := seen[k]; !ok { delete(tgt.Properties, k) } } + return nil } +func (s *schemaBuilder) buildNamedInterface(ftpe *types.Named, flist []*ast.Field, decl *entityDecl, schema *spec.Schema, seen map[string]string) (hasAllOf bool, err error) { + o := ftpe.Obj() + var afld *ast.Field + + for _, an := range flist { + if len(an.Names) != 0 { + continue + } + + tpp := decl.Pkg.TypesInfo.Types[an.Type] + if tpp.Type.String() != o.Type().String() { + continue + } + + // decl. + debugLog("maybe interface field %s: %s(%T)", o.Name(), o.Type().String(), o.Type()) + afld = an + break + } + + if afld == nil { + debugLog("can't find source associated with %s", ftpe.String()) + return hasAllOf, nil + } + + // if the field is annotated with swagger:ignore, ignore it + if ignored(afld.Doc) { + return hasAllOf, nil + } + + if !allOfMember(afld.Doc) { + var newSch spec.Schema + if err = s.buildEmbedded(o.Type(), &newSch, seen); err != nil { + return hasAllOf, err + } + schema.AllOf = append(schema.AllOf, newSch) + hasAllOf = true + + return hasAllOf, nil + } + + hasAllOf = true + + var newSch spec.Schema + // when the embedded struct is annotated with swagger:allOf it will be used as allOf property + // otherwise the fields will just be included as normal properties + if err = s.buildAllOf(o.Type(), &newSch); err != nil { + return hasAllOf, err + } + + if afld.Doc != nil { + for _, cmt := range afld.Doc.List { + for _, ln := range strings.Split(cmt.Text, "\n") { + matches := rxAllOf.FindStringSubmatch(ln) + ml := len(matches) + if ml <= 1 { + continue + } + + mv := matches[ml-1] + if mv != "" { + schema.AddExtension("x-class", mv) + } + } + } + } + + schema.AllOf = append(schema.AllOf, newSch) + + return hasAllOf, nil +} + func (s *schemaBuilder) buildFromStruct(decl *entityDecl, st *types.Struct, schema *spec.Schema, seen map[string]string) error { - s.ctx.FindComments(decl.Pkg, decl.Type.Obj().Name()) - cmt, hasComments := s.ctx.FindComments(decl.Pkg, decl.Type.Obj().Name()) + s.ctx.FindComments(decl.Pkg, decl.Obj().Name()) + cmt, hasComments := s.ctx.FindComments(decl.Pkg, decl.Obj().Name()) if !hasComments { cmt = new(ast.CommentGroup) } @@ -693,15 +1074,19 @@ func (s *schemaBuilder) buildFromStruct(decl *entityDecl, st *types.Struct, sche var tgt *spec.Schema hasAllOf := false - for i := 0; i < st.NumFields(); i++ { + for i := range st.NumFields() { fld := st.Field(i) if !fld.Anonymous() { + // e.g. struct { _ struct{} } debugLog("skipping field %q for allOf scan because not anonymous", fld.Name()) continue } tg := st.Tag(i) - debugLog("maybe allof field(%t) %s: %s (%T) [%q](anon: %t, embedded: %t)", fld.IsField(), fld.Name(), fld.Type().String(), fld.Type(), tg, fld.Anonymous(), fld.Embedded()) + debugLog( + "maybe allof field(%t) %s: %s (%T) [%q](anon: %t, embedded: %t)", + fld.IsField(), fld.Name(), fld.Type().String(), fld.Type(), tg, fld.Anonymous(), fld.Embedded(), + ) var afld *ast.Field ans, _ := astutil.PathEnclosingInterval(decl.File, fld.Pos(), fld.Pos()) // debugLog("got %d nodes (exact: %t)", len(ans), isExact) @@ -734,7 +1119,9 @@ func (s *schemaBuilder) buildFromStruct(decl *entityDecl, st *types.Struct, sche continue } - if !allOfMember(afld.Doc) { + _, isAliased := fld.Type().(*types.Alias) + + if !allOfMember(afld.Doc) && !isAliased { if tgt == nil { tgt = schema } @@ -743,6 +1130,11 @@ func (s *schemaBuilder) buildFromStruct(decl *entityDecl, st *types.Struct, sche } continue } + + if isAliased { + debugLog("alias member in struct: %v", fld) + } + // if this created an allOf property then we have to rejig the schema var // because all the fields collected that aren't from embedded structs should go in // their own proper schema @@ -789,7 +1181,7 @@ func (s *schemaBuilder) buildFromStruct(decl *entityDecl, st *types.Struct, sche } tgt.Typed("object", "") - for i := 0; i < st.NumFields(); i++ { + for i := range st.NumFields() { fld := st.Field(i) tg := st.Tag(i) @@ -804,7 +1196,6 @@ func (s *schemaBuilder) buildFromStruct(decl *entityDecl, st *types.Struct, sche var afld *ast.Field ans, _ := astutil.PathEnclosingInterval(decl.File, fld.Pos(), fld.Pos()) - // debugLog("got %d nodes (exact: %t)", len(ans), isExact) for _, an := range ans { at, valid := an.(*ast.Field) if !valid { @@ -894,79 +1285,174 @@ func (s *schemaBuilder) buildFromStruct(decl *entityDecl, st *types.Struct, sche func (s *schemaBuilder) buildAllOf(tpe types.Type, schema *spec.Schema) error { debugLog("allOf %s", tpe.Underlying()) + switch ftpe := tpe.(type) { case *types.Pointer: return s.buildAllOf(ftpe.Elem(), schema) case *types.Named: - switch utpe := ftpe.Underlying().(type) { - case *types.Struct: - decl, found := s.ctx.FindModel(ftpe.Obj().Pkg().Path(), ftpe.Obj().Name()) - if found { - if ftpe.Obj().Pkg().Path() == "time" && ftpe.Obj().Name() == "Time" { - schema.Typed("string", "date-time") - return nil - } - if sfnm, isf := strfmtName(decl.Comments); isf { - schema.Typed("string", sfnm) - return nil - } - if decl.HasModelAnnotation() { - return s.makeRef(decl, schemaTypable{schema, 0}) - } - return s.buildFromStruct(decl, utpe, schema, make(map[string]string)) - } + return s.buildNamedAllOf(ftpe, schema) + case *types.Alias: + debugLog("allOf member is alias %v => %v", ftpe, ftpe.Rhs()) + tgt := schemaTypable{schema: schema} + return s.buildAlias(ftpe, tgt) + case *types.TypeParam: + log.Printf("WARNING: generic type parameters are not supported yet %[1]v (%[1]T). Skipped", ftpe) + return nil + case *types.Chan: + log.Printf("WARNING: channels are not supported %[1]v (%[1]T). Skipped", ftpe) + return nil + case *types.Signature: + log.Printf("WARNING: functions are not supported %[1]v (%[1]T). Skipped", ftpe) + return nil + default: + log.Printf("WARNING: missing allOf parser for a %T, skipping field", ftpe) + return fmt.Errorf("unable to resolve allOf member for: %v", ftpe) + } +} + +func (s *schemaBuilder) buildNamedAllOf(ftpe *types.Named, schema *spec.Schema) error { + switch utpe := ftpe.Underlying().(type) { + case *types.Struct: + decl, found := s.ctx.FindModel(ftpe.Obj().Pkg().Path(), ftpe.Obj().Name()) + if !found { return fmt.Errorf("can't find source file for struct: %s", ftpe.String()) - case *types.Interface: - decl, found := s.ctx.FindModel(ftpe.Obj().Pkg().Path(), ftpe.Obj().Name()) - if found { - if sfnm, isf := strfmtName(decl.Comments); isf { - schema.Typed("string", sfnm) - return nil - } - if decl.HasModelAnnotation() { - return s.makeRef(decl, schemaTypable{schema, 0}) - } - return s.buildFromInterface(decl, utpe, schema, make(map[string]string)) - } + } + + if isStdTime(ftpe.Obj()) { + schema.Typed("string", "date-time") + return nil + } + + if sfnm, isf := strfmtName(decl.Comments); isf { + schema.Typed("string", sfnm) + return nil + } + + if decl.HasModelAnnotation() { + return s.makeRef(decl, schemaTypable{schema, 0}) + } + + return s.buildFromStruct(decl, utpe, schema, make(map[string]string)) + case *types.Interface: + decl, found := s.ctx.FindModel(ftpe.Obj().Pkg().Path(), ftpe.Obj().Name()) + if !found { return fmt.Errorf("can't find source file for interface: %s", ftpe.String()) - default: - log.Printf("WARNING: can't figure out object type for allOf named type (%T): %v", ftpe, ftpe.Underlying()) - return fmt.Errorf("unable to locate source file for allOf %s", utpe.String()) } + + if sfnm, isf := strfmtName(decl.Comments); isf { + schema.Typed("string", sfnm) + return nil + } + + if decl.HasModelAnnotation() { + return s.makeRef(decl, schemaTypable{schema, 0}) + } + + return s.buildFromInterface(decl, utpe, schema, make(map[string]string)) + case *types.TypeParam: + log.Printf("WARNING: generic type parameters are not supported yet %[1]v (%[1]T). Skipped", ftpe) + return nil + case *types.Chan: + log.Printf("WARNING: channels are not supported %[1]v (%[1]T). Skipped", ftpe) + return nil + case *types.Signature: + log.Printf("WARNING: functions are not supported %[1]v (%[1]T). Skipped", ftpe) + return nil default: - log.Printf("WARNING: Missing allOf parser for a %T, skipping field", ftpe) - return fmt.Errorf("unable to resolve allOf member for: %v", ftpe) + log.Printf( + "WARNING: can't figure out object type for allOf named type (%T): %v", + ftpe, utpe, + ) + return fmt.Errorf("unable to locate source file for allOf (%T): %v", + ftpe, utpe, + ) } } func (s *schemaBuilder) buildEmbedded(tpe types.Type, schema *spec.Schema, seen map[string]string) error { - debugLog("embedded %s", tpe.Underlying()) + debugLog("embedded %v", tpe.Underlying()) + switch ftpe := tpe.(type) { case *types.Pointer: return s.buildEmbedded(ftpe.Elem(), schema, seen) case *types.Named: - debugLog("embedded named type: %T", ftpe.Underlying()) - switch utpe := ftpe.Underlying().(type) { - case *types.Struct: - decl, found := s.ctx.FindModel(ftpe.Obj().Pkg().Path(), ftpe.Obj().Name()) - if found { - return s.buildFromStruct(decl, utpe, schema, seen) - } + return s.buildNamedEmbedded(ftpe, schema, seen) + case *types.Alias: + debugLog("embedded alias %v => %v", ftpe, ftpe.Rhs()) + tgt := schemaTypable{schema, 0} + return s.buildAlias(ftpe, tgt) + case *types.Union: // e.g. type X interface{ ~uint16 | ~float32 } + log.Printf("WARNING: union type constraints are not supported yet %[1]v (%[1]T). Skipped", ftpe) + return nil + case *types.TypeParam: + log.Printf("WARNING: generic type parameters are not supported yet %[1]v (%[1]T). Skipped", ftpe) + return nil + case *types.Chan: + log.Printf("WARNING: channels are not supported %[1]v (%[1]T). Skipped", ftpe) + return nil + case *types.Signature: + log.Printf("WARNING: functions are not supported %[1]v (%[1]T). Skipped", ftpe) + return nil + default: + log.Printf("WARNING: Missing embedded parser for a %T, skipping model\n", ftpe) + return nil + } +} + +func (s *schemaBuilder) buildNamedEmbedded(ftpe *types.Named, schema *spec.Schema, seen map[string]string) error { + debugLog("embedded named type: %T", ftpe.Underlying()) + if unsupportedBuiltin(ftpe) { + log.Printf("WARNING: skipped unsupported builtin type: %v", ftpe) + + return nil + } + + switch utpe := ftpe.Underlying().(type) { + case *types.Struct: + decl, found := s.ctx.FindModel(ftpe.Obj().Pkg().Path(), ftpe.Obj().Name()) + if !found { return fmt.Errorf("can't find source file for struct: %s", ftpe.String()) - case *types.Interface: - decl, found := s.ctx.FindModel(ftpe.Obj().Pkg().Path(), ftpe.Obj().Name()) - if found { - return s.buildFromInterface(decl, utpe, schema, seen) - } + } + + return s.buildFromStruct(decl, utpe, schema, seen) + case *types.Interface: + if utpe.Empty() { + return nil + } + o := ftpe.Obj() + if isAny(o) { + return nil + } + if isStdError(o) { + tgt := schemaTypable{schema: schema} + tgt.AddExtension("x-go-type", o.Name()) + return swaggerSchemaForType(o.Name(), tgt) + } + mustNotBeABuiltinType(o) + + decl, found := s.ctx.FindModel(o.Pkg().Path(), o.Name()) + if !found { return fmt.Errorf("can't find source file for struct: %s", ftpe.String()) - default: - log.Printf("WARNING: can't figure out object type for embedded named type (%T): %v", ftpe, ftpe.Underlying()) } + return s.buildFromInterface(decl, utpe, schema, seen) + case *types.Union: // e.g. type X interface{ ~uint16 | ~float32 } + log.Printf("WARNING: union type constraints are not supported yet %[1]v (%[1]T). Skipped", utpe) + return nil + case *types.TypeParam: + log.Printf("WARNING: generic type parameters are not supported yet %[1]v (%[1]T). Skipped", utpe) + return nil + case *types.Chan: + log.Printf("WARNING: channels are not supported %[1]v (%[1]T). Skipped", utpe) + return nil + case *types.Signature: + log.Printf("WARNING: functions are not supported %[1]v (%[1]T). Skipped", utpe) + return nil default: - log.Printf("WARNING: Missing embedded parser for a %T, skipping model\n", ftpe) + log.Printf("WARNING: can't figure out object type for embedded named type (%T): %v", + ftpe, utpe, + ) return nil } - return nil } func (s *schemaBuilder) makeRef(decl *entityDecl, prop swaggerTypable) error { @@ -991,7 +1477,7 @@ func (s *schemaBuilder) createParser(nm string, schema, ps *spec.Schema, fld *as if ps.Ref.String() == "" { sp.setDescription = func(lines []string) { ps.Description = joinDropLast(lines) - enumDesc := getEnumDesc(ps.VendorExtensible.Extensions) + enumDesc := getEnumDesc(ps.Extensions) if enumDesc != "" { ps.Description += "\n" + enumDesc } @@ -1070,7 +1556,7 @@ func (s *schemaBuilder) createParser(nm string, schema, ps *spec.Schema, fld *as } return otherTaggers, nil default: - return nil, fmt.Errorf("unknown field type ele for %q", nm) + return nil, fmt.Errorf("unknown field type element for %q", nm) } } // check if this is a primitive, if so parse the validations from the @@ -1178,3 +1664,29 @@ func isFieldStringable(tpe ast.Expr) bool { } return false } + +func isTextMarshaler(tpe types.Type) bool { + encodingPkg, err := importer.Default().Import("encoding") + if err != nil { + return false + } + ifc := encodingPkg.Scope().Lookup("TextMarshaler").Type().Underlying().(*types.Interface) // TODO: there is a better way to check this + + return types.Implements(tpe, ifc) +} + +func isStdTime(o *types.TypeName) bool { + return o.Pkg() != nil && o.Pkg().Name() == "time" && o.Name() == "Time" +} + +func isStdError(o *types.TypeName) bool { + return o.Pkg() == nil && o.Name() == "error" +} + +func isStdJSONRawMessage(o *types.TypeName) bool { + return o.Pkg() != nil && o.Pkg().Path() == "encoding/json" && o.Name() == "RawMessage" +} + +func isAny(o *types.TypeName) bool { + return o.Pkg() == nil && o.Name() == "any" +} diff --git a/vendor/github.com/go-swagger/go-swagger/codescan/spec.go b/vendor/github.com/go-swagger/go-swagger/codescan/spec.go index 20c4e1022..148360a3f 100644 --- a/vendor/github.com/go-swagger/go-swagger/codescan/spec.go +++ b/vendor/github.com/go-swagger/go-swagger/codescan/spec.go @@ -46,6 +46,8 @@ type specBuilder struct { } func (s *specBuilder) Build() (*spec.Swagger, error) { + // this initial scan step is skipped if !scanModels. + // Discovered dependencies should however be resolved. if err := s.buildModels(); err != nil { return nil, err } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/debug.go b/vendor/github.com/go-swagger/go-swagger/generator/debug.go index 61b4b8d48..ceb64c724 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/debug.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/debug.go @@ -36,7 +36,7 @@ func debugOptions() { } // debugLog wraps log.Printf with a debug-specific logger -func debugLog(frmt string, args ...interface{}) { +func debugLog(frmt string, args ...any) { if Debug { _, file, pos, _ := runtime.Caller(1) generatorLogger.Printf("%s:%d: %s", filepath.Base(file), pos, @@ -45,11 +45,11 @@ func debugLog(frmt string, args ...interface{}) { } // debugLogAsJSON unmarshals its last arg as pretty JSON -func debugLogAsJSON(frmt string, args ...interface{}) { +func debugLogAsJSON(frmt string, args ...any) { if Debug { var dfrmt string _, file, pos, _ := runtime.Caller(1) - dargs := make([]interface{}, 0, len(args)+2) + dargs := make([]any, 0, len(args)+2) dargs = append(dargs, filepath.Base(file), pos) if len(args) > 0 { dfrmt = "%s:%d: " + frmt + "\n%s" diff --git a/vendor/github.com/go-swagger/go-swagger/generator/doc.go b/vendor/github.com/go-swagger/go-swagger/generator/doc.go index 49cbf3950..bd4639a00 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/doc.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/doc.go @@ -17,7 +17,7 @@ Package generator provides the code generation library for go-swagger. # Generating data types -The general idea is that you should rarely see interface{} in the generated code. +The general idea is that you should rarely see any in the generated code. You get a complete representation of a swagger document in somewhat idiomatic go. To do so, there is a set of mapping patterns that are applied, diff --git a/vendor/github.com/go-swagger/go-swagger/generator/language.go b/vendor/github.com/go-swagger/go-swagger/generator/language.go index 68e911663..bd49f9746 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/language.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/language.go @@ -13,8 +13,9 @@ import ( "sort" "strings" - "github.com/go-openapi/swag" "golang.org/x/tools/imports" + + "github.com/go-openapi/swag" ) var ( @@ -30,15 +31,50 @@ func initLanguage() { moduleRe = regexp.MustCompile(`module[ \t]+([^\s]+)`) } +// FormatOption allows for more flexible code formatting settings +type FormatOption func(*formatOptions) + +type formatOptions struct { + imports.Options + localPrefixes []string +} + +// WithFormatLocalPrefixes adds local prefixes to group imports +func WithFormatLocalPrefixes(prefixes ...string) FormatOption { + return func(o *formatOptions) { + o.localPrefixes = append(o.localPrefixes, prefixes...) + } +} + +var defaultFormatOptions = formatOptions{ + Options: imports.Options{ + TabIndent: true, + TabWidth: 2, + Fragment: true, + Comments: true, + }, + localPrefixes: []string{"github.com/go-openapi"}, +} + +func formatOptionsWithDefault(opts []FormatOption) formatOptions { + o := defaultFormatOptions + + for _, apply := range opts { + apply(&o) + } + + return o +} + // LanguageOpts to describe a language to the code generator type LanguageOpts struct { ReservedWords []string - BaseImportFunc func(string) string `json:"-"` - ImportsFunc func(map[string]string) string `json:"-"` - ArrayInitializerFunc func(interface{}) (string, error) `json:"-"` + BaseImportFunc func(string) string `json:"-"` + ImportsFunc func(map[string]string) string `json:"-"` + ArrayInitializerFunc func(any) (string, error) `json:"-"` reservedWordsSet map[string]struct{} initialized bool - formatFunc func(string, []byte) ([]byte, error) + formatFunc func(string, []byte, ...FormatOption) ([]byte, error) fileNameFunc func(string) string // language specific source file naming rules dirNameFunc func(string) string // language specific directory naming rules } @@ -107,10 +143,12 @@ func (l *LanguageOpts) ManglePackagePath(name string, suffix string) string { } // FormatContent formats a file with a language specific formatter -func (l *LanguageOpts) FormatContent(name string, content []byte) ([]byte, error) { +func (l *LanguageOpts) FormatContent(name string, content []byte, opts ...FormatOption) ([]byte, error) { if l.formatFunc != nil { - return l.formatFunc(name, content) + return l.formatFunc(name, content, opts...) } + + // unformatted content return content, nil } @@ -123,7 +161,7 @@ func (l *LanguageOpts) imports(imports map[string]string) string { } // arrayInitializer builds a litteral array -func (l *LanguageOpts) arrayInitializer(data interface{}) (string, error) { +func (l *LanguageOpts) arrayInitializer(data any) (string, error) { if l.ArrayInitializerFunc != nil { return l.ArrayInitializerFunc(data) } @@ -204,13 +242,10 @@ func GoLangOpts() *LanguageOpts { "continue", "for", "import", "return", "var", } - opts.formatFunc = func(ffn string, content []byte) ([]byte, error) { - opts := new(imports.Options) - opts.TabIndent = true - opts.TabWidth = 2 - opts.Fragment = true - opts.Comments = true - return imports.Process(ffn, content, opts) + opts.formatFunc = func(ffn string, content []byte, opts ...FormatOption) ([]byte, error) { + o := formatOptionsWithDefault(opts) + imports.LocalPrefix = strings.Join(o.localPrefixes, ",") // regroup these packages + return imports.Process(ffn, content, &o.Options) } opts.fileNameFunc = func(name string) string { @@ -253,10 +288,10 @@ func GoLangOpts() *LanguageOpts { return strings.Join(result, "\n") } - opts.ArrayInitializerFunc = func(data interface{}) (string, error) { - // ArrayInitializer constructs a Go literal initializer from interface{} literals. - // e.g. []interface{}{"a", "b"} is transformed in {"a","b",} - // e.g. map[string]interface{}{ "a": "x", "b": "y"} is transformed in {"a":"x","b":"y",}. + opts.ArrayInitializerFunc = func(data any) (string, error) { + // ArrayInitializer constructs a Go literal initializer from any literals. + // e.g. []any{"a", "b"} is transformed in {"a","b",} + // e.g. map[string]any{ "a": "x", "b": "y"} is transformed in {"a":"x","b":"y",}. // // NOTE: this is currently used to construct simple slice intializers for default values. // This allows for nicer slice initializers for slices of primitive types and avoid systematic use for json.Unmarshal(). diff --git a/vendor/github.com/go-swagger/go-swagger/generator/media.go b/vendor/github.com/go-swagger/go-swagger/generator/media.go index 239926dc8..c3c57eb06 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/media.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/media.go @@ -44,6 +44,7 @@ var knownProducers = map[string]string{ "xml": "runtime.XMLProducer()", "txt": "runtime.TextProducer()", "bin": "runtime.ByteStreamProducer()", + "csv": "runtime.CSVProducer()", "urlform": "runtime.DiscardProducer", "multipartform": "runtime.DiscardProducer", } @@ -54,6 +55,7 @@ var knownConsumers = map[string]string{ "xml": "runtime.XMLConsumer()", "txt": "runtime.TextConsumer()", "bin": "runtime.ByteStreamConsumer()", + "csv": "runtime.CSVConsumer()", "urlform": "runtime.DiscardConsumer", "multipartform": "runtime.DiscardConsumer", } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/model.go b/vendor/github.com/go-swagger/go-swagger/generator/model.go index ca5b87a09..b9c7c93a6 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/model.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/model.go @@ -153,12 +153,12 @@ func makeGenDefinition(name, pkg string, schema spec.Schema, specDoc *loads.Docu // this means that the immediate content of the top level definitions has at least one validation. // // If none is found at this level and that no special case where no Validate() method is exposed at all - // (e.g. io.ReadCloser and interface{} types and their aliases), then there is an empty Validate() method which + // (e.g. io.ReadCloser and any types and their aliases), then there is an empty Validate() method which // just return nil (the object abides by the runtime.Validatable interface, but knows it has nothing to validate). // // We do this at the top level because of the possibility of aliased types which always bubble up validation to types which // are referring to them. This results in correct but inelegant code with empty validations. - gd.GenSchema.HasValidations = shallowValidationLookup(gd.GenSchema) + gd.HasValidations = shallowValidationLookup(gd.GenSchema) } return gd, err } @@ -196,7 +196,7 @@ func shallowValidationLookup(sch GenSchema) bool { for _, p := range sch.Properties { // Using a base type within another structure triggers validation of the base type. // The discriminator property in the base type definition itself does not. - if (p.HasValidations || p.Required) && !(sch.IsBaseType && p.Name == sch.DiscriminatorField) || (p.IsAliased || p.IsComplexObject) && !(p.IsInterface || p.IsStream) { + if (p.HasValidations || p.Required) && (!sch.IsBaseType || p.Name != sch.DiscriminatorField) || (p.IsAliased || p.IsComplexObject) && !p.IsInterface && !p.IsStream { return true } } @@ -207,7 +207,7 @@ func shallowValidationLookup(sch GenSchema) bool { return false } - if sch.HasAdditionalProperties && sch.AdditionalProperties != nil && (sch.AdditionalProperties.HasValidations || sch.AdditionalProperties.Required || sch.AdditionalProperties.IsAliased && !(sch.AdditionalProperties.IsInterface || sch.AdditionalProperties.IsStream)) { + if sch.HasAdditionalProperties && sch.AdditionalProperties != nil && (sch.AdditionalProperties.HasValidations || sch.AdditionalProperties.Required || sch.AdditionalProperties.IsAliased && !sch.AdditionalProperties.IsInterface && !sch.AdditionalProperties.IsStream) { return true } @@ -318,8 +318,8 @@ func makeGenDefinitionHierarchy(name, pkg, container string, schema spec.Schema, if err != nil { return nil, err } - gs.GenSchema.IsBaseType = true - gs.GenSchema.IsExported = true + gs.IsBaseType = true + gs.IsExported = true pg.GenSchema.AllOf[i] = gs.GenSchema schPtr := &(pg.GenSchema.AllOf[i]) if schPtr.AdditionalItems != nil { @@ -367,6 +367,7 @@ func makeGenDefinitionHierarchy(name, pkg, container string, schema spec.Schema, TargetImportPath: opts.LanguageOpts.baseImport(opts.Target), }, Package: modelPkg, + CliPackage: opts.CliPackage, GenSchema: pg.GenSchema, DependsOn: pg.Dependencies, DefaultImports: defaultImports, @@ -802,7 +803,7 @@ func (sg *schemaGenContext) buildProperties() error { return err } - // whatever the validations says, if we have an interface{}, do not validate + // whatever the validations says, if we have an any, do not validate // NOTE: this may be the case when the type is left empty and we get a Enum validation. if emprop.GenSchema.IsInterface || emprop.GenSchema.IsStream { emprop.GenSchema.HasValidations = false @@ -829,7 +830,7 @@ func (sg *schemaGenContext) buildProperties() error { if rsch == nil { return errors.New("spec.ResolveRef returned nil schema") } - if rsch != nil && rsch.Ref.String() != "" { + if rsch.Ref.String() != "" { ref = rsch.Ref continue } @@ -868,7 +869,7 @@ func (sg *schemaGenContext) buildProperties() error { // a base type property is always validated against the base type // exception: for the base type definition itself (see shallowValidationLookup()) - if (hv || emprop.GenSchema.IsBaseType) && !(emprop.GenSchema.IsInterface || emprop.GenSchema.IsStream) { + if (hv || emprop.GenSchema.IsBaseType) && !emprop.GenSchema.IsInterface && !emprop.GenSchema.IsStream { emprop.GenSchema.HasValidations = true } if ttpe.HasAdditionalItems && sch.AdditionalItems.Schema != nil { @@ -962,7 +963,7 @@ func (sg *schemaGenContext) buildAllOf() error { if (tpe.IsAnonymous && len(sch.AllOf) > 0) || (sch.Ref.String() == "" && !tpe.IsComplexObject && (tpe.IsArray || tpe.IsInterface || tpe.IsPrimitive)) { // cases where anonymous structures cause the creation of a new type: // - nested allOf: this one is itself a AllOf: build a new type for it - // - anonymous simple types for edge cases: array, primitive, interface{} + // - anonymous simple types for edge cases: array, primitive, any // NOTE: when branches are aliased or anonymous, the nullable property in the branch type is lost. name := swag.ToVarName(goName(&sch, sg.makeRefName()+"AllOf"+strconv.Itoa(i))) debugLog("building anonymous nested allOf in %s: %s", sg.Name, name) @@ -1012,7 +1013,7 @@ func (sg *schemaGenContext) buildAllOf() error { } // lift validations when complex or ref'ed - if (comprop.GenSchema.IsComplexObject || comprop.Schema.Ref.String() != "") && !(comprop.GenSchema.IsInterface || comprop.GenSchema.IsStream) { + if (comprop.GenSchema.IsComplexObject || comprop.Schema.Ref.String() != "") && !comprop.GenSchema.IsInterface && !comprop.GenSchema.IsStream { comprop.GenSchema.HasValidations = true } sg.MergeResult(comprop, true) @@ -1132,7 +1133,7 @@ func (mt *mapStack) Build() error { mt.Context.GenSchema.AdditionalProperties = &cp.GenSchema // lift validations - if (csch.Ref.String() != "" || cp.GenSchema.IsAliased) && !(cp.GenSchema.IsInterface || cp.GenSchema.IsStream) { + if (csch.Ref.String() != "" || cp.GenSchema.IsAliased) && !cp.GenSchema.IsInterface && !cp.GenSchema.IsStream { // - we stopped on a ref, or anything else that require we call its Validate() method // - if the alias / ref is on an interface (or stream) type: no validation mt.Context.GenSchema.HasValidations = true @@ -1191,7 +1192,7 @@ func (mt *mapStack) Build() error { // lift validations c := &cur.Next.Context.GenSchema - if (cur.Next.Context.Schema.Ref.String() != "" || c.IsAliased) && !(c.IsInterface || c.IsStream) { + if (cur.Next.Context.Schema.Ref.String() != "" || c.IsAliased) && !c.IsInterface && !c.IsStream { // - we stopped on a ref, or anything else that require we call its Validate() // - if the alias / ref is on an interface (or stream) type: no validation cur.Context.GenSchema.HasValidations = true @@ -1218,8 +1219,8 @@ func (mt *mapStack) HasMore() bool { } /* currently unused: -func (mt *mapStack) Dict() map[string]interface{} { - res := make(map[string]interface{}) +func (mt *mapStack) Dict() map[string]any { + res := make(map[string]any) res["context"] = mt.Context.Schema if mt.Next != nil { res["next"] = mt.Next.Dict() @@ -1262,7 +1263,7 @@ func (sg *schemaGenContext) buildAdditionalProperties() error { if addp.Schema == nil { // this is for AdditionalProperties:true|false if addp.Allows { - // additionalProperties: true is rendered as: map[string]interface{} + // additionalProperties: true is rendered as: map[string]any addp.Schema = &spec.Schema{} addp.Schema.Typed("object", "") @@ -1281,7 +1282,7 @@ func (sg *schemaGenContext) buildAdditionalProperties() error { } sg.MergeResult(cp, false) sg.GenSchema.AdditionalProperties = &cp.GenSchema - debugLog("added interface{} schema for additionalProperties[allows == true], IsInterface=%t", cp.GenSchema.IsInterface) + debugLog("added any schema for additionalProperties[allows == true], IsInterface=%t", cp.GenSchema.IsInterface) } return nil } @@ -1348,6 +1349,9 @@ func (sg *schemaGenContext) buildAdditionalProperties() error { // rewrite value expression for arrays and arrays of arrays in maps (rendered as map[string][][]...) if sg.GenSchema.AdditionalProperties.IsArray { // maps of slices are where an override may take effect + if sg.GenSchema.AdditionalProperties.Items == nil { + return fmt.Errorf("items schema not defined for additional property in %q", sg.Name) + } sg.GenSchema.AdditionalProperties.Items.IsMapNullOverride = sg.GenSchema.AdditionalProperties.IsMapNullOverride sg.GenSchema.AdditionalProperties.Items.ValueExpression = sg.GenSchema.ValueExpression + "[" + comprop.KeyVar + "]" + "[" + sg.GenSchema.AdditionalProperties.IndexVar + "]" ap := sg.GenSchema.AdditionalProperties.Items @@ -1359,7 +1363,7 @@ func (sg *schemaGenContext) buildAdditionalProperties() error { } // lift validation - if (sg.GenSchema.AdditionalProperties.IsComplexObject || sg.GenSchema.AdditionalProperties.IsAliased || sg.GenSchema.AdditionalProperties.Required) && !(sg.GenSchema.AdditionalProperties.IsInterface || sg.GenSchema.IsStream) { + if (sg.GenSchema.AdditionalProperties.IsComplexObject || sg.GenSchema.AdditionalProperties.IsAliased || sg.GenSchema.AdditionalProperties.Required) && !sg.GenSchema.AdditionalProperties.IsInterface && !sg.GenSchema.IsStream { sg.GenSchema.HasValidations = true } return nil @@ -1508,7 +1512,7 @@ func (sg *schemaGenContext) buildArray() error { schemaCopy.HasValidations = true } - if (elProp.Schema.Ref.String() != "" || elProp.GenSchema.IsAliased) && !(elProp.GenSchema.IsInterface || elProp.GenSchema.IsStream) { + if (elProp.Schema.Ref.String() != "" || elProp.GenSchema.IsAliased) && !elProp.GenSchema.IsInterface && !elProp.GenSchema.IsStream { schemaCopy.HasValidations = true } @@ -1649,7 +1653,7 @@ func (sg *schemaGenContext) buildAdditionalItems() error { } // lift validations when complex is not anonymous or ref'ed - if (tpe.IsComplexObject || it.Schema.Ref.String() != "") && !(tpe.IsInterface || tpe.IsStream) { + if (tpe.IsComplexObject || it.Schema.Ref.String() != "") && !tpe.IsInterface && !tpe.IsStream { it.GenSchema.HasValidations = true } @@ -1742,7 +1746,7 @@ func (sg *schemaGenContext) shortCircuitNamedRef() (bool, error) { sg.MergeResult(pg, true) sg.GenSchema = pg.GenSchema sg.GenSchema.resolvedType = tpe - sg.GenSchema.resolvedType.IsSuperAlias = true + sg.GenSchema.IsSuperAlias = true sg.GenSchema.IsBaseType = tpe.IsBaseType return true, nil @@ -2063,7 +2067,7 @@ func (sg *schemaGenContext) makeGenSchema() error { sg.GenSchema.resolvedType = tpe sg.GenSchema.Required = sg.Required // assume we validate everything but interface and io.Reader - validation may be disabled by using the noValidation hint - sg.GenSchema.HasValidations = !(tpe.IsInterface || tpe.IsStream || tpe.SkipExternalValidation) + sg.GenSchema.HasValidations = !tpe.IsInterface && !tpe.IsStream && !tpe.SkipExternalValidation sg.GenSchema.IsAliased = sg.GenSchema.HasValidations log.Printf("INFO: type %s is external, with inferred spec type %s, referred to as %s", sg.GenSchema.Name, sg.GenSchema.GoType, extType) @@ -2145,10 +2149,10 @@ func (sg *schemaGenContext) makeGenSchema() error { // - aliased primitive of a formatter type which is not a stringer // // but not for: - // - interface{} + // - any // - io.Reader gs := sg.GenSchema - sg.GenSchema.WantsMarshalBinary = !(gs.IsInterface || gs.IsStream || gs.IsBaseType) && + sg.GenSchema.WantsMarshalBinary = !gs.IsInterface && !gs.IsStream && !gs.IsBaseType && (gs.IsTuple || gs.IsComplexObject || gs.IsAdditionalProperties || (gs.IsPrimitive && gs.IsAliased && gs.IsCustomFormatter && !strings.Contains(gs.Zero(), `("`))) debugLog("finished gen schema for %q", sg.Name) diff --git a/vendor/github.com/go-swagger/go-swagger/generator/operation.go b/vendor/github.com/go-swagger/go-swagger/generator/operation.go index a2098c375..a8ad73f6c 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/operation.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/operation.go @@ -251,7 +251,7 @@ func paramMappings(params map[string]spec.Parameter) (map[string]map[string]stri // In order to avoid unstable generation, adopt same naming convention // for all parameters with same name across locations. - seenIDs := make(map[string]interface{}, len(params)) + seenIDs := make(map[string]any, len(params)) for id, p := range params { debugLog("paramMappings: params: id=%s, In=%q, Name=%q", id, p.In, p.Name) // guard against possible validation failures and/or skipped issues @@ -286,7 +286,7 @@ func paramMappings(params map[string]spec.Parameter) (map[string]map[string]stri // // NOTE: this merely protects the timeout field in the client parameter struct, // fields "Context" and "HTTPClient" remain exposed to name conflicts. -func renameTimeout(seenIDs map[string]interface{}, timeoutName string) string { +func renameTimeout(seenIDs map[string]any, timeoutName string) string { if seenIDs == nil { return timeoutName } @@ -520,6 +520,7 @@ func (b *codeGenOpBuilder) MakeOperation() (GenOperation, error) { PrincipalIsNullable: b.GenOpts.PrincipalIsNullable(), ExternalDocs: trimExternalDoc(operation.ExternalDocs), + ReturnErrors: b.GenOpts.ReturnErrors, }, nil } @@ -566,6 +567,7 @@ func (b *codeGenOpBuilder) MakeResponse(receiver, name string, isSuccess bool, r StrictResponders: b.GenOpts.StrictResponders, OperationName: b.Name, Examples: examples, + ReturnErrors: b.GenOpts.ReturnErrors, } // prepare response headers @@ -778,7 +780,7 @@ func (b *codeGenOpBuilder) MakeParameter(receiver string, resolver *typeResolver SchemaValidations: param.Validations(), } - res.ZeroValue = res.resolvedType.Zero() + res.ZeroValue = res.Zero() hasChildValidations := false if param.Items != nil { @@ -964,7 +966,7 @@ func (b *codeGenOpBuilder) setBodyParamValidation(p *GenParameter) { // composition of primitive fields must be properly identified: hack this through _, isPrimitive := primitives[s.GoType] _, isFormatter := customFormatters[s.GoType] - isComposedPrimitive := s.IsPrimitive && !(isPrimitive || isFormatter) + isComposedPrimitive := s.IsPrimitive && !isPrimitive && !isFormatter hasSimpleBodyParams = !s.IsComplexObject && !s.IsAliased && !isComposedPrimitive && !doNot hasModelBodyParams = (s.IsComplexObject || s.IsAliased || isComposedPrimitive) && !doNot @@ -972,12 +974,12 @@ func (b *codeGenOpBuilder) setBodyParamValidation(p *GenParameter) { if s.IsArray && s.Items != nil { it := s.Items doNot = it.IsInterface || it.IsStream || it.IsBase64 - hasSimpleBodyItems = !it.IsComplexObject && !(it.IsAliased || doNot) + hasSimpleBodyItems = !it.IsComplexObject && !it.IsAliased && !doNot hasModelBodyItems = (it.IsComplexObject || it.IsAliased) && !doNot } if s.IsMap && s.AdditionalProperties != nil { it := s.AdditionalProperties - hasSimpleBodyMap = !it.IsComplexObject && !(it.IsAliased || doNot) + hasSimpleBodyMap = !it.IsComplexObject && !it.IsAliased && !doNot hasModelBodyMap = !hasSimpleBodyMap && !doNot } } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/shared.go b/vendor/github.com/go-swagger/go-swagger/generator/shared.go index 75ed251fe..abbc466d9 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/shared.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/shared.go @@ -24,6 +24,7 @@ import ( "path" "path/filepath" "reflect" + "regexp" "sort" "strings" "text/template" @@ -351,6 +352,7 @@ type GenOptsCommon struct { StrictResponders bool AcceptDefinitionsOnly bool WantsRootedErrorPath bool + ReturnErrors bool templates *Repository // a shallow clone of the global template repository } @@ -503,7 +505,7 @@ func (g *GenOpts) EnsureDefaults() error { return nil } -func (g *GenOpts) location(t *TemplateOpts, data interface{}) (string, string, error) { +func (g *GenOpts) location(t *TemplateOpts, data any) (string, string, error) { v := reflect.Indirect(reflect.ValueOf(data)) fld := v.FieldByName("Name") var name string @@ -549,7 +551,7 @@ func (g *GenOpts) location(t *TemplateOpts, data interface{}) (string, string, e Name, CliAppName, Package, APIPackage, ServerPackage, ClientPackage, CliPackage, ModelPackage, MainPackage, Target string Tags []string UseTags bool - Context interface{} + Context any }{ Name: name, CliAppName: g.CliAppName, @@ -578,7 +580,7 @@ func (g *GenOpts) location(t *TemplateOpts, data interface{}) (string, string, e return pthBuf.String(), fileName(fNameBuf.String()), nil } -func (g *GenOpts) render(t *TemplateOpts, data interface{}) ([]byte, error) { +func (g *GenOpts) render(t *TemplateOpts, data any) ([]byte, error) { var templ *template.Template if strings.HasPrefix(strings.ToLower(t.Source), "asset:") { @@ -635,7 +637,7 @@ func (g *GenOpts) render(t *TemplateOpts, data interface{}) ([]byte, error) { // generated code is reformatted ("linted"), which gives an // additional level of checking. If this step fails, the generated // code is still dumped, for template debugging purposes. -func (g *GenOpts) write(t *TemplateOpts, data interface{}) error { +func (g *GenOpts) write(t *TemplateOpts, data any) error { dir, fname, err := g.location(t, data) if err != nil { return fmt.Errorf("failed to resolve template location for template %s: %w", t.Name, err) @@ -670,7 +672,8 @@ func (g *GenOpts) write(t *TemplateOpts, data interface{}) error { var writeerr error if !t.SkipFormat { - formatted, err = g.LanguageOpts.FormatContent(filepath.Join(dir, fname), content) + baseImport := g.LanguageOpts.baseImport(g.Target) + formatted, err = g.LanguageOpts.FormatContent(filepath.Join(dir, fname), content, WithFormatLocalPrefixes(baseImport)) if err != nil { log.Printf("source formatting failed on template-generated source (%q for %s). Check that your template produces valid code", filepath.Join(dir, fname), t.Name) writeerr = os.WriteFile(filepath.Join(dir, fname), content, 0o644) // #nosec @@ -854,7 +857,13 @@ func (g *GenOpts) PrincipalAlias() string { return principal } +var ifaceRex = regexp.MustCompile(`^interface\s\{\s*\}$`) + func (g *GenOpts) resolvePrincipal() (string, string, string) { + if ifaceRex.MatchString(g.Principal) { + return "", "any", "" + } + dotLocation := strings.LastIndex(g.Principal, ".") if dotLocation < 0 { return "", g.Principal, "" @@ -1085,12 +1094,12 @@ func gatherURISchemes(swsp *spec.Swagger, operation spec.Operation) ([]string, [ return schemes, extraSchemes } -func dumpData(data interface{}) error { +func dumpData(data any) error { bb, err := json.MarshalIndent(data, "", " ") if err != nil { return err } - fmt.Fprintln(os.Stdout, string(bb)) // TODO(fred): not testable + _, _ = fmt.Fprintln(os.Stdout, string(bb)) // TODO(fred): not testable return nil } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/spec.go b/vendor/github.com/go-swagger/go-swagger/generator/spec.go index df3528a62..a177b0c1b 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/spec.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/spec.go @@ -166,7 +166,7 @@ func findSwaggerSpec(nm string) (string, error) { // WithAutoXOrder amends the spec to specify property order as they appear // in the spec (supports yaml documents only). func WithAutoXOrder(specPath string) string { - lookFor := func(ele interface{}, key string) (yamlv2.MapSlice, bool) { + lookFor := func(ele any, key string) (yamlv2.MapSlice, bool) { if slice, ok := ele.(yamlv2.MapSlice); ok { for _, v := range slice { if v.Key == key { @@ -179,8 +179,8 @@ func WithAutoXOrder(specPath string) string { return nil, false } - var addXOrder func(interface{}) - addXOrder = func(element interface{}) { + var addXOrder func(any) + addXOrder = func(element any) { if props, ok := lookFor(element, "properties"); ok { for i, prop := range props { if pSlice, ok := prop.Value.(yamlv2.MapSlice); ok { @@ -249,8 +249,8 @@ func WithAutoXOrder(specPath string) string { } // BytesToYAMLDoc converts a byte slice into a YAML document -func BytesToYAMLv2Doc(data []byte) (interface{}, error) { - var canary map[interface{}]interface{} // validate this is an object and not a different type +func BytesToYAMLv2Doc(data []byte) (any, error) { + var canary map[any]any // validate this is an object and not a different type if err := yamlv2.Unmarshal(data, &canary); err != nil { return nil, err } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/structs.go b/vendor/github.com/go-swagger/go-swagger/generator/structs.go index 145228881..61b63d6e0 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/structs.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/structs.go @@ -29,6 +29,7 @@ type GenDefinition struct { GenCommon GenSchema Package string + CliPackage string Imports map[string]string DefaultImports map[string]string ExtraSchemas GenSchemaList @@ -94,7 +95,7 @@ type GenSchema struct { Parents []string IncludeValidator bool IncludeModel bool - Default interface{} + Default any WantsMarshalBinary bool // do we generate MarshalBinary interface? StructTags []string ExtraImports map[string]string // non-standard imports detected when using external types @@ -236,7 +237,7 @@ type sharedValidations struct { HasContextValidations bool Required bool HasSliceValidations bool - ItemsEnum []interface{} + ItemsEnum []any // NOTE: "patternProperties" and "dependencies" not supported by Swagger 2.0 } @@ -261,11 +262,12 @@ type GenResponse struct { Imports map[string]string DefaultImports map[string]string - Extensions map[string]interface{} + Extensions map[string]any StrictResponders bool OperationName string Examples GenResponseExamples + ReturnErrors bool } // GenResponseExamples is a sortable collection []GenResponseExample @@ -278,7 +280,7 @@ func (g GenResponseExamples) Less(i, j int) bool { return g[i].MediaType < g[j]. // GenResponseExample captures an example provided for a response for some mime type type GenResponseExample struct { MediaType string - Example interface{} + Example any } // GenHeader represents a header on a response for code generation @@ -297,7 +299,7 @@ type GenHeader struct { Title string Description string - Default interface{} + Default any HasDefault bool CollectionFormat string @@ -373,7 +375,7 @@ type GenParameter struct { // Unused // BodyParam *GenParameter - Default interface{} + Default any HasDefault bool ZeroValue string AllowEmptyValue bool @@ -393,7 +395,7 @@ type GenParameter struct { HasSimpleBodyMap bool HasModelBodyMap bool - Extensions map[string]interface{} + Extensions map[string]any } // IsQueryParam returns true when this parameter is a query param @@ -636,9 +638,10 @@ type GenOperation struct { ConsumesMediaTypes []string TimeoutName string - Extensions map[string]interface{} + Extensions map[string]any StrictResponders bool + ReturnErrors bool ExternalDocs *spec.ExternalDocumentation Produces []string // original produces for operation (for doc) Consumes []string // original consumes for operation (for doc) @@ -730,6 +733,16 @@ func (g GenSerGroups) Len() int { return len(g) } func (g GenSerGroups) Swap(i, j int) { g[i], g[j] = g[j], g[i] } func (g GenSerGroups) Less(i, j int) bool { return g[i].Name < g[j].Name } +// NumSerializers yields the total number of serializer entries in this group. +func (g GenSerGroups) NumSerializers() int { + n := 0 + for _, group := range g { + n += len(group.AllSerializers) + } + + return n +} + // GenSerGroup represents a group of serializers: this links a serializer to a list of // prioritized media types (mime). type GenSerGroup struct { @@ -777,7 +790,7 @@ type GenSecurityScheme struct { Flow string AuthorizationURL string TokenURL string - Extensions map[string]interface{} + Extensions map[string]any ScopesDesc []GenSecurityScope } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/template_repo.go b/vendor/github.com/go-swagger/go-swagger/generator/template_repo.go index 2c377372d..94a8493b4 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/template_repo.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/template_repo.go @@ -3,6 +3,7 @@ package generator import ( "bytes" "encoding/json" + "errors" "fmt" "log" "math" @@ -18,10 +19,11 @@ import ( "unicode" "github.com/Masterminds/sprig/v3" + "github.com/kr/pretty" + "github.com/go-openapi/inflect" "github.com/go-openapi/runtime" "github.com/go-openapi/swag" - "github.com/kr/pretty" ) var ( @@ -34,6 +36,8 @@ var ( templates *Repository docFormat map[string]string + + errInternal = errors.New("internal error detected in templates") ) func initTemplateRepo() { @@ -109,7 +113,7 @@ func DefaultFuncMap(lang *LanguageOpts) template.FuncMap { "headerDocType": func(header GenHeader) string { return resolvedDocType(header.SwaggerType, header.SwaggerFormat, header.Child) }, - "schemaDocType": func(in interface{}) string { + "schemaDocType": func(in any) string { switch schema := in.(type) { case GenSchema: return resolvedDocSchemaType(schema.SwaggerType, schema.SwaggerFormat, schema.Items) @@ -139,7 +143,7 @@ func DefaultFuncMap(lang *LanguageOpts) template.FuncMap { "cleanupEnumVariant": cleanupEnumVariant, "gt0": gt0, "path": errorPath, - "cmdName": func(in interface{}) (string, error) { + "cmdName": func(in any) (string, error) { // builds the name of a CLI command for a single operation op, isOperation := in.(GenOperation) if !isOperation { @@ -153,7 +157,7 @@ func DefaultFuncMap(lang *LanguageOpts) template.FuncMap { return name, nil // TODO }, - "cmdGroupName": func(in interface{}) (string, error) { + "cmdGroupName": func(in any) (string, error) { // builds the name of a group of CLI commands opGroup, ok := in.(GenOperationGroup) if !ok { @@ -183,6 +187,19 @@ func DefaultFuncMap(lang *LanguageOpts) template.FuncMap { // builds a flag description variable in CLI commands return fmt.Sprintf("flag%sDescription", pascalize(in)) }, + "printGoLiteral": func(in any) string { + // printGoLiteral replaces printf "%#v" and replaces "interface {}" by "any" + return interfaceReplacer.Replace(fmt.Sprintf("%#v", in)) + }, + // assert is used to inject into templates and check for inconsistent/invalid data. + // This is for now being used during test & debug of templates. + "assert": func(msg string, assertion bool) (string, error) { + if !assertion { + return "", fmt.Errorf("%v: %w", msg, errInternal) + } + + return "", nil + }, } for k, v := range extra { @@ -503,26 +520,26 @@ func findDependencies(n parse.Node) []string { } } case *parse.IfNode: - for _, dep := range findDependencies(node.BranchNode.List) { + for _, dep := range findDependencies(node.List) { depMap[dep] = true } - for _, dep := range findDependencies(node.BranchNode.ElseList) { + for _, dep := range findDependencies(node.ElseList) { depMap[dep] = true } case *parse.RangeNode: - for _, dep := range findDependencies(node.BranchNode.List) { + for _, dep := range findDependencies(node.List) { depMap[dep] = true } - for _, dep := range findDependencies(node.BranchNode.ElseList) { + for _, dep := range findDependencies(node.ElseList) { depMap[dep] = true } case *parse.WithNode: - for _, dep := range findDependencies(node.BranchNode.List) { + for _, dep := range findDependencies(node.List) { depMap[dep] = true } - for _, dep := range findDependencies(node.BranchNode.ElseList) { + for _, dep := range findDependencies(node.ElseList) { depMap[dep] = true } @@ -542,7 +559,7 @@ func (t *Repository) flattenDependencies(templ *template.Template, dependencies dependencies = make(map[string]bool) } - deps := findDependencies(templ.Tree.Root) + deps := findDependencies(templ.Root) for _, d := range deps { if _, found := dependencies[d]; !found { @@ -615,7 +632,7 @@ func (t *Repository) DumpTemplates() { fmt.Fprintf(buf, "## %s\n", name) fmt.Fprintf(buf, "Defined in `%s`\n", t.files[name]) - if deps := findDependencies(templ.Tree.Root); len(deps) > 0 { + if deps := findDependencies(templ.Root); len(deps) > 0 { fmt.Fprintf(buf, "####requires \n - %v\n\n\n", strings.Join(deps, "\n - ")) } fmt.Fprintln(buf, "\n---") @@ -625,7 +642,7 @@ func (t *Repository) DumpTemplates() { // FuncMap functions -func asJSON(data interface{}) (string, error) { +func asJSON(data any) (string, error) { b, err := json.Marshal(data) if err != nil { return "", err @@ -633,7 +650,7 @@ func asJSON(data interface{}) (string, error) { return string(b), nil } -func asPrettyJSON(data interface{}) (string, error) { +func asPrettyJSON(data any) (string, error) { b, err := json.MarshalIndent(data, "", " ") if err != nil { return "", err @@ -658,7 +675,7 @@ func dropPackage(str string) string { // return true if the GoType str contains pkg. For example "model.MyType" -> true, "MyType" -> false func containsPkgStr(str string) bool { dropped := dropPackage(str) - return !(dropped == str) + return dropped != str } func padSurround(entry, padWith string, i, ln int) string { @@ -749,11 +766,11 @@ func cleanupEnumVariant(in string) string { return replaced } -func dict(values ...interface{}) (map[string]interface{}, error) { +func dict(values ...any) (map[string]any, error) { if len(values)%2 != 0 { return nil, fmt.Errorf("expected even number of arguments, got %d", len(values)) } - dict := make(map[string]interface{}, len(values)/2) + dict := make(map[string]any, len(values)/2) for i := 0; i < len(values); i += 2 { key, ok := values[i].(string) if !ok { @@ -764,7 +781,7 @@ func dict(values ...interface{}) (map[string]interface{}, error) { return dict, nil } -func isInteger(arg interface{}) bool { +func isInteger(arg any) bool { // is integer determines if a value may be represented by an integer switch val := arg.(type) { case int8, int16, int32, int, int64, uint8, uint16, uint32, uint, uint64: @@ -893,7 +910,7 @@ func gt0(in *int64) bool { return in != nil && *in > 0 } -func errorPath(in interface{}) (string, error) { +func errorPath(in any) (string, error) { // For schemas: // errorPath returns an empty string litteral when the schema path is empty. // It provides a shorthand for template statements such as: @@ -981,7 +998,10 @@ func errorPath(in interface{}) (string, error) { const mdNewLine = "</br>" -var mdNewLineReplacer = strings.NewReplacer("\r\n", mdNewLine, "\n", mdNewLine, "\r", mdNewLine) +var ( + mdNewLineReplacer = strings.NewReplacer("\r\n", mdNewLine, "\n", mdNewLine, "\r", mdNewLine) + interfaceReplacer = strings.NewReplacer("interface {}", "any") +) func markdownBlock(in string) string { in = strings.TrimSpace(in) diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/cli.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/cli.gotmpl index 073e33cfa..93f3d432e 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/cli.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/cli.gotmpl @@ -2,7 +2,7 @@ {{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} -package {{ .GenOpts.CliPackage }} +package {{ toPackageName .GenOpts.CliPackage }} // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command @@ -35,7 +35,7 @@ var ( ) // logDebugf writes debug log to stdout -func logDebugf(format string, v ...interface{}) { +func logDebugf(format string, v ...any) { if !debug{ return } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/completion.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/completion.gotmpl index c115cc1a9..cb8e8008b 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/completion.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/completion.gotmpl @@ -4,7 +4,7 @@ {{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} -package {{ .GenOpts.CliPackage }} +package {{ toPackageName .GenOpts.CliPackage }} // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command @@ -14,7 +14,6 @@ import( ) func makeGenCompletionCmd() *cobra.Command{ - var completionCmd = &cobra.Command{ Use: "completion [bash|zsh|fish|powershell]", Short: "Generate completion script", @@ -59,19 +58,22 @@ PowerShell: `, DisableFlagsInUseLine: true, ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, - Args: cobra.ExactValidArgs(1), - Run: func(cmd *cobra.Command, args []string) { + Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), + RunE: func(cmd *cobra.Command, args []string) error { switch args[0] { case "bash": - cmd.Root().GenBashCompletion(os.Stdout) + return cmd.Root().GenBashCompletion(os.Stdout) case "zsh": - cmd.Root().GenZshCompletion(os.Stdout) + return cmd.Root().GenZshCompletion(os.Stdout) case "fish": - cmd.Root().GenFishCompletion(os.Stdout, true) + return cmd.Root().GenFishCompletion(os.Stdout, true) case "powershell": - cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) + return cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) + default: + return fmt.Errorf("unsupported shell %q", args[0]) } }, } + return completionCmd -}
\ No newline at end of file +} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/modelcli.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/modelcli.gotmpl index 49b106bf9..6f3e62aaa 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/modelcli.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/modelcli.gotmpl @@ -4,7 +4,7 @@ {{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} -package cli +package {{ toPackageName .CliPackage }} // This file was generated by the swagger tool. // Editing this file might prove futile when you re-run the swagger generate command diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/operation.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/operation.gotmpl index dc09dac07..5a39709d8 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/operation.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/operation.gotmpl @@ -120,7 +120,7 @@ func retrieveOperation{{pascalize $operationGroup }}{{ pascalize $operation }}{{ {{/*Note anonymous body schema is not pointer*/}} {{ flagValueVar .Name }} := {{if containsPkgStr .GoType}}{{ .GoType }}{{else}}{{ .Pkg }}.{{.GoType}}{{ end }}{} if err := json.Unmarshal([]byte({{ flagValueVar .Name }}Str), &{{ flagValueVar .Name }}); err!= nil{ - return fmt.Errorf("cannot unmarshal {{ $flagStr }} string in {{.GoType}}: %v", err), false + return fmt.Errorf("cannot unmarshal {{ $flagStr }} string in {{.GoType}}: %w", err), false } m.{{ .ID }} = {{- if .IsNullable }}&{{- end }}{{ flagValueVar .Name }} {{- else }} @@ -165,10 +165,12 @@ func retrieveOperation{{pascalize $operationGroup }}{{ pascalize $operation }}{{ {{- /*TODO: handle multiple success response case*/}} func parseOperation{{pascalize .Package}}{{ pascalize .Name }}Result({{- if .SuccessResponse }}{{ range $i, $v := .SuccessResponses }} resp{{$i}} *{{$v.Package}}.{{pascalize $v.Name}},{{- end }}{{- end }} respErr error) (string, error){ if respErr != nil { - {{- /*error is of type default model. If we can cast, then print the resp.*/}} - {{ if .DefaultResponse }} {{with .DefaultResponse}} - {{ if .Schema }} - var iRespD interface{} = respErr +{{- /*error is of type default model. If we can cast, then print the resp.*/}} +{{- if .DefaultResponse }} + // default response + {{- with .DefaultResponse}} + {{- if .Schema }} + var iRespD any = respErr respD, ok := iRespD.(*{{ .Package }}.{{ pascalize .Name }}) if ok { if !swag.IsZero(respD) && !swag.IsZero(respD.Payload) { @@ -179,31 +181,39 @@ func parseOperation{{pascalize .Package}}{{ pascalize .Name }}Result({{- if .Suc return string(msgStr), nil } } - {{ else }} + {{- else }} // Non schema case: warning {{.Name}} is not supported - {{ end }} - {{ end }} {{ end }} - {{- range $i, $v := .Responses }} - {{ if .Schema }} - var iResp{{$i}} interface{} = respErr - resp{{$i}}, ok := iResp{{$i}}.(*{{ .Package }}.{{ pascalize .Name }}) + {{- end }} + {{- end }} +{{- end }} + + // responses +{{- range $i, $v := .Responses }} + {{- if .Schema }} + var iResp{{$i}} any = respErr + eresp{{$i}}, ok := iResp{{$i}}.(*{{ .Package }}.{{ pascalize .Name }}) if ok { - if !swag.IsZero(resp{{$i}}) && !swag.IsZero(resp{{$i}}.Payload) { - msgStr,err := json.Marshal(resp{{$i}}.Payload) + // the error response has a payload + if !swag.IsZero(eresp{{$i}}) && !swag.IsZero(eresp{{$i}}.Payload) { + msgStr,err := json.Marshal(eresp{{$i}}.Payload) if err != nil{ return "", err } return string(msgStr), nil } } - {{ else }} + + {{- else }} // Non schema case: warning {{.Name}} is not supported - {{ end }} - {{ end }} + + {{- end }} +{{- end }} return "", respErr } - {{- range $i, $v := .SuccessResponses }} - {{ if .Schema }} + + // success responses +{{- range $i, $v := .SuccessResponses }} + {{- if .Schema }} {{- with .Schema}} if !swag.IsZero(resp{{$i}}) && !swag.IsZero(resp{{$i}}.Payload) { {{- if or .IsComplexObject .IsArray .IsMap }} @@ -216,11 +226,13 @@ func parseOperation{{pascalize .Package}}{{ pascalize .Name }}Result({{- if .Suc {{- end }} return string(msgStr), nil } + {{- end }} - {{ else }} + {{- else }} // warning: non schema response {{.Name}} is not supported by go-swagger cli yet. - {{ end }} - {{ end }} + + {{- end }} +{{- end }} return "", nil } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/registerflag.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/registerflag.gotmpl index fb0dba04b..eb576f1a3 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/registerflag.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/cli/registerflag.gotmpl @@ -21,7 +21,7 @@ {{ end }} {{ define "flagdefaultvar" }} - var {{ flagDefaultVar .Name }} {{ .GoType }} {{ if .Default }}= {{ printf "%#v" .Default }}{{ end }} + var {{ flagDefaultVar .Name }} {{ .GoType }} {{ if .Default }}= {{ printGoLiteral .Default }}{{ end }} {{ end }} {{/* Not used. CLI does not mark flag as required, and required will be checked by validation in future */}} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/client/client.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/client/client.gotmpl index 85a996372..44d7ecc27 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/client/client.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/client/client.gotmpl @@ -133,7 +133,7 @@ type ClientService interface { {{ blockcomment .Description }}{{ end }}{{ else if .Description}}{{ blockcomment .Description }}{{ else }}{{ humanize .Name }} API{{ end }} */ func (a *Client) {{ pascalize .Name }}(params *{{ pascalize .Name }}Params{{ if .Authorized }}, authInfo runtime.ClientAuthInfoWriter{{end}}{{ if .HasStreamingResponse }}, writer io.Writer{{ end }}, opts ...ClientOption) {{ if .SuccessResponse }}({{ range .SuccessResponses }}*{{ pascalize .Name }}, {{ end }}{{ end }}error{{ if .SuccessResponse }}){{ end }} { - // TODO: Validate the params before sending + // NOTE: parameters are not validated before sending if params == nil { params = New{{ pascalize .Name }}Params() } @@ -141,9 +141,9 @@ func (a *Client) {{ pascalize .Name }}(params *{{ pascalize .Name }}Params{{ if ID: {{ printf "%q" .Name }}, Method: {{ printf "%q" .Method }}, PathPattern: {{ printf "%q" .Path }}, - ProducesMediaTypes: {{ printf "%#v" .ProducesMediaTypes }}, - ConsumesMediaTypes: {{ printf "%#v" .ConsumesMediaTypes }}, - Schemes: {{ printf "%#v" .Schemes }}, + ProducesMediaTypes: {{ printGoLiteral .ProducesMediaTypes }}, + ConsumesMediaTypes: {{ printGoLiteral .ConsumesMediaTypes }}, + Schemes: {{ printGoLiteral .Schemes }}, Params: params, Reader: &{{ pascalize .Name }}Reader{formats: a.formats{{ if .HasStreamingResponse }}, writer: writer{{ end }}},{{ if .Authorized }} AuthInfo: authInfo,{{ end}} @@ -153,44 +153,63 @@ func (a *Client) {{ pascalize .Name }}(params *{{ pascalize .Name }}Params{{ if for _, opt := range opts { opt(op) } - {{ $length := len .SuccessResponses }} + {{- $length := len .SuccessResponses }} {{ if .SuccessResponse }}result{{else}}_{{ end }}, err := a.transport.Submit(op) if err != nil { return {{ if .SuccessResponse }}{{ padSurround "nil" "nil" 0 $length }}, {{ end }}err } {{- if .SuccessResponse }} {{- if eq $length 1 }} + + // only one success response has to be checked success, ok := result.(*{{ pascalize .SuccessResponse.Name }}) if ok { return success,nil } - // unexpected success response - {{- if .DefaultResponse }}{{/* if a default response is provided, fill this and return an error */}} + + // unexpected success response. + {{- if .DefaultResponse }} + // + // a default response is provided: fill this and return an error unexpectedSuccess := result.(*{{ pascalize .DefaultResponse.Name }}) + return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) {{- else }} - // safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue + + // no default response is defined. + // + // safeguard: normally, in the absence of a default response, unknown success responses return an error above: so this is a codegen issue msg := fmt.Sprintf("unexpected success response for {{ .Name }}: API contract not enforced by server. Client expected to get an error, but got: %T", result) panic(msg) {{- end }} - {{- else }}{{/* several possible success responses */}} + {{- else }} + + // several success responses have to be checked switch value := result.(type) { {{- range $i, $v := .SuccessResponses }} case *{{ pascalize $v.Name }}: return {{ padSurround "value" "nil" $i $length }}, nil {{- end }} } - {{- if .DefaultResponse }}{{/* if a default response is provided, fill this and return an error */}} - // unexpected success response + {{- if .DefaultResponse }} + + // unexpected success response. + // + // a default response is provided: fill this and return an error unexpectedSuccess := result.(*{{ pascalize .DefaultResponse.Name }}) return {{ padSurround "nil" "nil" 0 $length }}, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) {{- else }} - // safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue + + // no default response is defined. + // + // safeguard: normally, in the absence of a default response, unknown success responses return an error above: so this is a codegen issue msg := fmt.Sprintf("unexpected success response for {{ $.Name }}: API contract not enforced by server. Client expected to get an error, but got: %T", result) panic(msg) {{- end }} {{- end }} {{- else }} + // no success response is defined: return nil + return nil {{- end }} } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/client/facade.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/client/facade.gotmpl index 287a75f92..5f2afc91c 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/client/facade.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/client/facade.gotmpl @@ -30,14 +30,14 @@ var Default = NewHTTPClient(nil) const ( // DefaultHost is the default Host // found in Meta (info) section of spec file - DefaultHost string = {{ printf "%#v" .Host }} + DefaultHost string = {{ printGoLiteral .Host }} // DefaultBasePath is the default BasePath // found in Meta (info) section of spec file - DefaultBasePath string = {{ printf "%#v" .BasePath }} + DefaultBasePath string = {{ printGoLiteral .BasePath }} ) // DefaultSchemes are the default schemes found in Meta (info) section of spec file -var DefaultSchemes = {{ printf "%#v" .Schemes }} +var DefaultSchemes = {{ printGoLiteral .Schemes }} // NewHTTPClient creates a new {{ humanize .Name }} HTTP client. func NewHTTPClient(formats strfmt.Registry) *{{ pascalize .Name }} { diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/client/response.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/client/response.gotmpl index dce21aa2f..52439945a 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/client/response.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/client/response.gotmpl @@ -197,7 +197,7 @@ func ({{ .ReceiverName }} *{{ pascalize .Name }}) readResponse(response runtime. {{- if not .Schema.IsBaseType }} // response payload - if err := consumer.Consume(response.Body(), {{ if not (or .Schema.IsComplexObject .Schema.IsStream) }}&{{ end}}{{ .ReceiverName }}.Payload); err != nil && err != io.EOF { + if err := consumer.Consume(response.Body(), {{ if not (or .Schema.IsComplexObject .Schema.IsStream) }}&{{ end}}{{ .ReceiverName }}.Payload); err != nil && !stderrors.Is(err,io.EOF) { return err } {{- end }} @@ -232,6 +232,7 @@ package {{ .Package }} import ( + stderrors "errors" "io" "net/http" @@ -254,7 +255,7 @@ type {{ pascalize .Name }}Reader struct { } // ReadResponse reads a server response into the received {{ .ReceiverName }}. -func ({{ .ReceiverName }} *{{ pascalize .Name }}Reader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { +func ({{ .ReceiverName }} *{{ pascalize .Name }}Reader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (any, error) { {{- if .Responses}} switch response.Code() { {{- end }} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/contrib/stratoscale/client/client.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/contrib/stratoscale/client/client.gotmpl index 3398815ec..a87d5a8ec 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/contrib/stratoscale/client/client.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/contrib/stratoscale/client/client.gotmpl @@ -64,15 +64,15 @@ type Client struct { {{ blockcomment .Description }}{{ end }}{{ else if .Description}}{{ blockcomment .Description }}{{ else }}{{ humanize .Name }} API{{ end }} */ func (a *Client) {{ pascalize .Name }}(ctx context.Context, params *{{ pascalize .Name }}Params{{ if .HasStreamingResponse }}, writer io.Writer{{ end }}) {{ if .SuccessResponse }}({{ range .SuccessResponses }}*{{ pascalize .Name }}, {{ end }}{{ end }}error{{ if .SuccessResponse }}){{ end }} { - {{ $length := len .SuccessResponses }} - {{ $success := .SuccessResponses }} + {{- $length := len .SuccessResponses }} + {{- $success := .SuccessResponses }} {{ if .Responses }}result{{else}}_{{end}}, err := a.transport.Submit(&runtime.ClientOperation{ ID: {{ printf "%q" .Name }}, Method: {{ printf "%q" .Method }}, PathPattern: {{ printf "%q" .Path }}, - ProducesMediaTypes: {{ printf "%#v" .ProducesMediaTypes }}, - ConsumesMediaTypes: {{ printf "%#v" .ConsumesMediaTypes }}, - Schemes: {{ printf "%#v" .Schemes }}, + ProducesMediaTypes: {{ printGoLiteral .ProducesMediaTypes }}, + ConsumesMediaTypes: {{ printGoLiteral .ConsumesMediaTypes }}, + Schemes: {{ printGoLiteral .Schemes }}, Params: params, Reader: &{{ pascalize .Name }}Reader{formats: a.formats{{ if .HasStreamingResponse }}, writer: writer{{ end }}}, {{ if .Authorized -}} @@ -85,25 +85,44 @@ func (a *Client) {{ pascalize .Name }}(ctx context.Context, params *{{ pascalize return {{ if $success }}{{ padSurround "nil" "nil" 0 $length }}, {{ end }}err } {{- if .Responses }} + {{- if gt (len .Responses) 1 }} + switch value := result.(type) { {{- range $i, $v := .Responses }} case *{{ pascalize $v.Name }}: - {{- if $v.IsSuccess }} + {{- if $v.IsSuccess }} return {{ if $success }}{{ padSurround "value" "nil" $i $length }},{{ end }}nil - {{- else }} + {{- else }} return {{ if $success }}{{ padSurround "nil" "nil" 0 $length }},{{ end }}runtime.NewAPIError("unsuccessful response", value, value.Code()) - {{- end }} + {{- end }} {{- end }} } - {{- if .DefaultResponse }} - // unexpected success response + {{- else }} + {{- $v := (index .Responses 0) }} + if value, ok := result.(*{{ pascalize $v.Name }}) ; ok { + {{- if $v.IsSuccess }} + return {{ if $success }}{{ padSurround "value" "nil" 0 $length }},{{ end }}nil + {{- else }} + return {{ if $success }}{{ padSurround "nil" "nil" 0 $length }},{{ end }}runtime.NewAPIError("unsuccessful response", value, value.Code()) + {{- end }} + } + {{- end }} + + // unexpected response. + {{- if .DefaultResponse }} + // + // a default response is provided: fill this and return an error unexpectedSuccess := result.(*{{ pascalize .DefaultResponse.Name }}) + return {{ if $success }}{{ padSurround "nil" "nil" 0 $length }}, {{ end }}runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code()) - {{- else }} - // safeguard: normally, absent a default response, unknown success responses return an error above: so this is a codegen issue + {{- else }} + + // no default response is defined. + // + // safeguard: normally, in the absence of a default response, unknown responses return an error above: so this is a codegen issue msg := fmt.Sprintf("unexpected success response for {{ .Name }}: API contract not enforced by server. Client expected to get an error, but got: %T", result) panic(msg) - {{- end }} + {{- end }} {{- else }} return nil {{- end }} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/contrib/stratoscale/client/facade.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/contrib/stratoscale/client/facade.gotmpl index 1d658978b..6b4245668 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/contrib/stratoscale/client/facade.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/contrib/stratoscale/client/facade.gotmpl @@ -28,14 +28,14 @@ import ( const ( // DefaultHost is the default Host // found in Meta (info) section of spec file - DefaultHost string = {{ printf "%#v" .Host }} + DefaultHost string = {{ printGoLiteral .Host }} // DefaultBasePath is the default BasePath // found in Meta (info) section of spec file - DefaultBasePath string = {{ printf "%#v" .BasePath }} + DefaultBasePath string = {{ printGoLiteral .BasePath }} ) // DefaultSchemes are the default schemes found in Meta (info) section of spec file -var DefaultSchemes = {{ printf "%#v" .Schemes }} +var DefaultSchemes = {{ printGoLiteral .Schemes }} type Config struct { // URL is the base URL of the upstream server diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/contrib/stratoscale/server/configureapi.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/contrib/stratoscale/server/configureapi.gotmpl index 03f8d6745..ecb7a6753 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/contrib/stratoscale/server/configureapi.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/contrib/stratoscale/server/configureapi.gotmpl @@ -27,30 +27,29 @@ import ( type contextKey string const AuthKey contextKey = "Auth" +{{- range .OperationGroups }} -{{ range .OperationGroups -}} //go:generate mockery --name {{ pascalize .Name}}API --inpackage /* {{ pascalize .Name }}API {{ .Description }} */ type {{ pascalize .Name }}API interface { -{{ range .Operations -}} - {{ if .Summary -}} +{{- range .Operations }} + {{- if .Summary }} /* {{ pascalize .Name }} {{ .Summary }} */ - {{ else if .Description -}} + {{- else if .Description }} /* {{ pascalize .Name }} {{ .Description }} */ - {{ end -}} + {{- end }} {{ pascalize .Name }}(ctx context.Context, params {{.Package}}.{{ pascalize .Name }}Params) middleware.Responder - -{{ end -}} +{{- end }} } -{{ end }} +{{- end }} // Config is configuration for Handler type Config struct { - {{ range .OperationGroups -}} + {{- range .OperationGroups }} {{ pascalize .Name }}API - {{ end -}} - Logger func(string, ...interface{}) + {{- end }} + Logger func(string, ...any) // InnerMiddleware is for the handler executors. These do not apply to the swagger.json document. // The middleware executes after routing but before authentication, binding and validation InnerMiddleware func(http.Handler) http.Handler @@ -58,21 +57,23 @@ type Config struct { // Authorizer is used to authorize a request after the Auth function was called using the "Auth*" functions // and the principal was stored in the context in the "AuthKey" context value. Authorizer func(*http.Request) error + {{- range .SecurityDefinitions }} + {{- if .IsBasicAuth }} - {{ range .SecurityDefinitions -}} - {{ if .IsBasicAuth -}} // Auth{{ pascalize .ID }} for basic authentication - Auth{{ pascalize .ID }} func(user string, pass string) ({{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}, error) - {{ end -}} - {{ if .IsAPIKeyAuth -}} + Auth{{ pascalize .ID }} func(user string, password string) ({{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}, error) + {{- end }} + {{- if .IsAPIKeyAuth }} + // Auth{{ pascalize .ID }} Applies when the "{{ .Name }}" {{ .Source }} is set Auth{{ pascalize .ID }} func(token string) ({{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}, error) - {{ end }} - {{ if .IsOAuth2 -}} - // Auth{{ pascalize .ID }} For OAuth2 authentication + {{- end }} + {{- if .IsOAuth2 }} + + // Auth{{ pascalize .ID }} for OAuth2 authentication Auth{{ pascalize .ID }} func(token string, scopes []string) ({{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}, error) - {{ end -}} - {{ end -}} + {{- end }} + {{- end }} // Authenticator to use for all APIKey authentication APIKeyAuthenticator func(string, string, security.TokenAuthentication) runtime.Authenticator @@ -80,13 +81,13 @@ type Config struct { BasicAuthenticator func(security.UserPassAuthentication) runtime.Authenticator // Authenticator to use for all Basic authentication BearerAuthenticator func(string, security.ScopedTokenAuthentication) runtime.Authenticator + {{- range .Consumes }} + {{- if .Implementation }} - {{ range .Consumes -}} - {{ if .Implementation -}} // {{ pascalize .Name }}Consumer is a {{ .Name }} consumer that will replace the default if not nil. {{ pascalize .Name }}Consumer runtime.Consumer - {{ end -}} - {{ end -}} + {{- end }} + {{- end }} } // Handler returns an http.Handler given the handler configuration @@ -102,7 +103,7 @@ func Handler(c Config) (http.Handler, error) { func HandlerAPI(c Config) (http.Handler, *{{.Package}}.{{ pascalize .Name }}API, error) { spec, err := loads.Analyzed(swaggerCopy(SwaggerJSON), "") if err != nil { - return nil, nil, fmt.Errorf("analyze swagger: %v", err) + return nil, nil, fmt.Errorf("analyze swagger: %w", err) } api := {{.Package}}.New{{ pascalize .Name }}API(spec) api.ServeError = errors.ServeError @@ -117,83 +118,96 @@ func HandlerAPI(c Config) (http.Handler, *{{.Package}}.{{ pascalize .Name }}API, if c.BearerAuthenticator != nil { api.BearerAuthenticator = c.BearerAuthenticator } + {{- range .Consumes }} - {{ range .Consumes -}} if c.{{ pascalize .Name }}Consumer != nil { api.{{ pascalize .Name }}Consumer = c.{{ pascalize .Name }}Consumer } else { - {{ if .Implementation -}} + {{- if .Implementation }} api.{{ pascalize .Name }}Consumer = {{ .Implementation }} - {{ else }} - api.{{ pascalize .Name }}Consumer = runtime.ConsumerFunc(func(r io.Reader, target interface{}) error { + {{- else }} + api.{{ pascalize .Name }}Consumer = runtime.ConsumerFunc(func(r io.Reader, target any) error { + _ = r + _ = target + return errors.NotImplemented("{{.Name}} consumer has not yet been implemented") }) - {{ end -}} + {{- end }} } - {{ end -}} - {{ range .Produces -}} - {{ if .Implementation -}} + {{- end }} + {{- range .Produces }} + {{- if .Implementation }} api.{{ pascalize .Name }}Producer = {{ .Implementation }} - {{ else -}} - api.{{ pascalize .Name }}Producer = runtime.ProducerFunc(func(w io.Writer, data interface{}) error { + {{- else }} + api.{{ pascalize .Name }}Producer = runtime.ProducerFunc(func(w io.Writer, data any) error { + _ = w + _ = data + return errors.NotImplemented("{{.Name}} producer has not yet been implemented") }) - {{ end -}} - {{ end -}} + {{- end }} + {{- end }} + {{- range .SecurityDefinitions }} + {{- if .IsBasicAuth }} - {{ range .SecurityDefinitions -}} - {{ if .IsBasicAuth -}} - api.{{ pascalize .ID }}Auth = func(user string, pass string) ({{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { + api.{{ pascalize .ID }}Auth = func(user string, password string) ({{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { if c.Auth{{ pascalize .ID }} == nil { - {{- if eq .Principal "interface{}" }} + {{- if eq .Principal "any" }} return "", nil - {{- else }} - panic("you specified a custom principal type, but did not provide the authenticator to provide this") - {{- end }} + {{- else }} + panic("you specified a custom principal type, but did not provide the authenticator to resolve a principal") + {{- end }} } - return c.Auth{{ pascalize .ID }}(user, pass) + + return c.Auth{{ pascalize .ID }}(user, password) } - {{ end -}} - {{ if .IsAPIKeyAuth -}} + {{- end }} + {{- if .IsAPIKeyAuth }} + api.{{ pascalize .ID }}Auth = func(token string) ({{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { if c.Auth{{ pascalize .ID }} == nil { - {{- if eq .Principal "interface{}" }} + {{- if eq .Principal "any" }} return token, nil - {{- else }} - panic("you specified a custom principal type, but did not provide the authenticator to provide this") - {{- end }} + {{- else }} + panic("you specified a custom principal type, but did not provide the authenticator to resolve a principal") + {{- end }} } + return c.Auth{{ pascalize .ID }}(token) } - {{ end }} - {{ if .IsOAuth2 -}} + {{- end }} + {{- if .IsOAuth2 }} + api.{{ pascalize .ID }}Auth = func(token string, scopes []string) ({{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { if c.Auth{{ pascalize .ID }} == nil { - {{- if eq .Principal "interface{}" }} + {{- if eq .Principal "any" }} return token, nil - {{- else }} - panic("you specified a custom principal type, but did not provide the authenticator to provide this") - {{- end }} + {{- else }} + panic("you specified a custom principal type, but did not provide the authenticator to resolve a principal") + {{- end }} } + return c.Auth{{ pascalize .ID }}(token, scopes) } - {{ end -}} - {{ end -}} + {{- end }} + {{- end }} + {{- if .SecurityDefinitions }} - {{ if .SecurityDefinitions -}} api.APIAuthorizer = authorizer(c.Authorizer) - {{ end -}} + {{- end }} + + {{- range .Operations }} - {{ range .Operations -}} api.{{if ne .Package $package}}{{pascalize .Package}}{{end}}{{ pascalize .Name }}Handler = {{- .PackageAlias }}.{{ pascalize .Name }}HandlerFunc(func(params {{.PackageAlias}}.{{ pascalize .Name }}Params{{if .Authorized}}, principal {{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}{{end}}) middleware.Responder { ctx := params.HTTPRequest.Context() - {{ if .Authorized -}} + {{- if .Authorized }} ctx = storeAuth(ctx, principal) - {{ end -}} - return c.{{pascalize .Package}}API.{{pascalize .Name}}(ctx, params) + {{- end }} + + return c.{{pascalize .Name}}(ctx, params) }) - {{ end -}} + {{- end }} api.ServerShutdown = func() { } return api.Serve(c.InnerMiddleware), api, nil @@ -209,7 +223,7 @@ func swaggerCopy(orig json.RawMessage) json.RawMessage { // authorizer is a helper function to implement the runtime.Authorizer interface. type authorizer func(*http.Request) error -func (a authorizer) Authorize(req *http.Request, principal interface{}) error { +func (a authorizer) Authorize(req *http.Request, principal any) error { if a == nil { return nil } @@ -217,6 +231,6 @@ func (a authorizer) Authorize(req *http.Request, principal interface{}) error { return a(req.WithContext(ctx)) } -func storeAuth(ctx context.Context, principal interface{}) context.Context { +func storeAuth(ctx context.Context, principal any) context.Context { return context.WithValue(ctx, AuthKey, principal) } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/header.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/header.gotmpl index a60cae1ea..4fc2ba18d 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/header.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/header.gotmpl @@ -10,6 +10,8 @@ package {{.Package}} // Editing this file might prove futile when you re-run the swagger generate command import ( + stderrors "errors" + "github.com/go-openapi/strfmt" {{- if .DefaultImports }} {{ imports .DefaultImports }} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/schemaembedded.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/schemaembedded.gotmpl index f86c27bc6..58e1a949c 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/schemaembedded.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/schemaembedded.gotmpl @@ -4,7 +4,7 @@ type {{ pascalize .Name }} struct { } func ({{.ReceiverName }} {{ if or .IsTuple .IsComplexObject }}*{{ end }}{{ if .Discriminates }}{{ camelize .Name }}{{ else if .IsExported }}{{ pascalize .Name }}{{ else }}{{ .Name }}{{ end }}) Validate(formats strfmt.Registry) error { - var f interface{} = {{ .ReceiverName }}.{{ dropPackage .ElemType.GoType }} + var f any = {{ .ReceiverName }}.{{ dropPackage .ElemType.GoType }} if v, ok := f.(runtime.Validatable) ; ok { return v.Validate(formats) } @@ -12,7 +12,7 @@ func ({{.ReceiverName }} {{ if or .IsTuple .IsComplexObject }}*{{ end }}{{ if .D } func ({{.ReceiverName }} {{ if or .IsTuple .IsComplexObject }}*{{ end }}{{ if .Discriminates }}{{ camelize .Name }}{{ else if .IsExported }}{{ pascalize .Name }}{{ else }}{{ .Name }}{{ end }}) ContextValidate(ctx context.Context, formats strfmt.Registry) error { - var f interface{} = {{ .ReceiverName }}.{{ dropPackage .ElemType.GoType }} + var f any = {{ .ReceiverName }}.{{ dropPackage .ElemType.GoType }} if v, ok := f.(runtime.ContextValidatable) ; ok { return v.ContextValidate(ctx, formats) } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/schemavalidator.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/schemavalidator.gotmpl index cee8a5dd6..341c34ef0 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/schemavalidator.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/schemavalidator.gotmpl @@ -1,16 +1,24 @@ {{ define "primitivefieldcontextvalidator" }} - {{ if .ReadOnly }} - if err := validate.ReadOnly(ctx, {{ path . }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil{ + {{- if .ReadOnly }} + if err := validate.ReadOnly(ctx, {{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil{ return err } - {{ end }} + {{- end }} {{ end }} {{ define "primitivefieldvalidator" }} {{ if .Required }} + {{- /* NOTE(fredbi): we have introduced a type conversion here a long time ago, and I can't remember why we did so. + + In all known cases this type conversion was superfluous. + + If there is a valid case when we need to coerce the .ValueExpression to the .GoType, + I've failed so far to produce a test for it. Removed the type conversion until we find when it could be + useful. + */}} {{- if and (eq .GoType "string") (not .IsNullable) }} - if err := validate.RequiredString({{ path . }}, {{ printf "%q" .Location }}, {{ if .IsAliased }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if .IsAliased }}){{ end }}); err != nil { + if err := validate.RequiredString({{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil { {{- else }} - if err := validate.Required({{ path . }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil { + if err := validate.Required({{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil { {{- end }} return err } @@ -52,7 +60,7 @@ {{ define "slicecontextvalidator" }} {{ if .ReadOnly }} - if err := validate.ReadOnly(ctx, {{ path . }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil{ + if err := validate.ReadOnly(ctx, {{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil{ return err } {{ end }} @@ -70,11 +78,15 @@ if {{ .ValueExpression }} != nil { {{- end }} if err := {{.ValueExpression }}.ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { return ve.ValidateName({{ path . }}) - } else if ce, ok := err.(*errors.CompositeError); ok { + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { return ce.ValidateName({{ path . }}) } + return err } {{- if and .IsNullable (not .IsMapNullOverride) }} @@ -137,11 +149,15 @@ if {{ .ValueExpression }} != nil { {{- end }} if err := {{.ValueExpression }}.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { return ve.ValidateName({{ path . }}) - } else if ce, ok := err.(*errors.CompositeError); ok { + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { return ce.ValidateName({{ path . }}) } + return err } {{- if and .IsNullable (not .IsMapNullOverride) }} @@ -312,11 +328,15 @@ if val != nil { {{- end }} if err := val.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName({{ path . }}) - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName({{ path . }}) + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName({{ path . }}) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName({{ path . }}) } + return err } {{- if and .IsNullable (not .IsMapNullOverride) }} @@ -372,11 +392,15 @@ if val != nil { {{- end }} if err := val.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName({{ path . }}) - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName({{ path . }}) + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName({{ path . }}) + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName({{ path . }}) } + return err } {{- if and .IsNullable (not .IsMapNullOverride) }} @@ -467,11 +491,15 @@ } {{ end }} if err := {{.ValueExpression }}.ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { return ve.ValidateName({{ path . }}) - } else if ce, ok := err.(*errors.CompositeError); ok { + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { return ce.ValidateName({{ path . }}) } + return err } {{- if and .IsNullable (not .IsMapNullOverride) }} @@ -568,11 +596,15 @@ if {{ .ValueExpression }} != nil { {{- end }} if err := {{.ValueExpression }}.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { + ve := new(errors.Validation) + if stderrors.As(err, &ve) { return ve.ValidateName({{ path . }}) - } else if ce, ok := err.(*errors.CompositeError); ok { + } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { return ce.ValidateName({{ path . }}) } + return err } {{- if or (and (or .IsNullable) (not .IsMapNullOverride)) .IsMap .IsArray }} @@ -608,7 +640,7 @@ // at https://github.com/go-swagger/go-swagger/issues {{- if .ReadOnly }} - if err := validate.ReadOnly{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ path . }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil { + if err := validate.ReadOnly{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}; err != nil { return err } {{- end }} @@ -619,7 +651,7 @@ {{- end }} {{- else if .IsArray }} {{ template "slicecontextvalidator" . }} - {{- else if and .IsMap (or (not .IsAliased) (and .IsAliased .IsInterface)) }}{{/* except for interface, the renderinf for aliased maps is performed by objectvalidator */}} + {{- else if and .IsMap (or (not .IsAliased) (and .IsAliased .IsInterface)) }}{{/* except for interface, the rendering for aliased maps is performed by objectvalidator */}} {{ template "mapcontextvalidator" . }} {{- else if or .IsComplexObject .IsTuple .IsAdditionalProperties .IsAliased }} {{ template "objectcontextvalidator" . }} @@ -631,7 +663,7 @@ {{- if .IsPrimitive }} {{- if .IsAliased }} {{- if and .Required (not .IsAnonymous) }} - if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ path . }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil { + if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil { return err } {{- end }} @@ -641,7 +673,7 @@ {{- end }} {{- else if and .IsCustomFormatter (or .HasValidations .Required) }}{{/* custom format not captured as primitive */}} {{- if .Required }} - if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ path . }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil { + if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil { return err } {{- end }} @@ -660,7 +692,7 @@ return errors.Required({{ path . }}, {{ printf "%q" .Location }}, {{ .ValueExpression }}) } {{- else }} - if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ path . }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil { + if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil { return err } {{- end }} @@ -672,7 +704,7 @@ return errors.Required({{ path . }}, {{ printf "%q" .Location }}, {{ .ValueExpression }}) } {{- else }} - if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ path . }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil { + if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil { return err } {{- end }} @@ -703,7 +735,7 @@ {{ template "primitivefieldvalidator" . }} {{- else if and .IsCustomFormatter (or .HasValidations .Required) }}{{/* custom format not captured as primitive */}} {{- if .Required }} - if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ path . }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil { + if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil { return err } {{- end }} @@ -804,7 +836,7 @@ const ( {{ end }} // for schema -var {{ camelize .Name }}Enum []interface{} +var {{ camelize .Name }}Enum []any func init() { var res []{{ template "dereffedSchemaType" . }} if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil { @@ -823,7 +855,7 @@ func ({{ .ReceiverName }} {{ if not .IsPrimitive }}*{{ end }}{{ if .IsExported } } {{ end }} {{ if .ItemsEnum }} -var {{ camelize .Name }}ItemsEnum []interface{} +var {{ camelize .Name }}ItemsEnum []any func init() { var res []{{ template "dereffedSchemaType" .Items }} @@ -845,7 +877,7 @@ func ({{ .ReceiverName }} *{{ if $.IsExported }}{{ pascalize $.Name }}{{ else }} {{ with .AdditionalProperties }} {{ if .Enum }} // for additional props -var {{ camelize .Name }}ValueEnum []interface{} +var {{ camelize .Name }}ValueEnum []any func init() { var res []{{ template "dereffedSchemaType" . }} @@ -929,7 +961,7 @@ func ({{.ReceiverName }} {{ if or .IsTuple .IsComplexObject .IsAdditionalPropert {{ range .Properties }} {{ if or .Required .HasValidations }} {{ if .Enum }} -var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []interface{} +var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []any func init() { var res []{{ template "dereffedSchemaType" . }} @@ -962,7 +994,7 @@ func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else } {{ end }} {{ if .ItemsEnum }} -var {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum []interface{} +var {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum []any func init() { var res []{{ template "dereffedSchemaType" .Items }} if err := json.Unmarshal([]byte(`{{ json .ItemsEnum }}`), &res); err != nil { @@ -982,7 +1014,7 @@ func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else {{ end }} {{ if .AdditionalItems }} {{ if .AdditionalItems.Enum }} -var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []interface{} +var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []any func init() { var res []{{ template "dereffedSchemaType" .AdditionalItems }} @@ -1005,7 +1037,7 @@ func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else {{ with .AdditionalProperties }} {{ if .Enum }} // additional properties value enum -var {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum []interface{} +var {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum []any func init() { var res []{{ template "dereffedSchemaType" . }} @@ -1063,7 +1095,7 @@ func ({{.ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else i {{ range .Properties }} {{ if and (ne $.DiscriminatorField .Name) (or .Required .HasValidations) }} {{ if .Enum }} -var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []interface{} +var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []any func init() { var res []{{ template "dereffedSchemaType" . }} @@ -1084,7 +1116,7 @@ func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else } {{ end }} {{ if .ItemsEnum }} -var {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum []interface{} +var {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum []any func init() { var res []{{ template "dereffedSchemaType" .Items }} @@ -1105,7 +1137,7 @@ func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else {{ end }} {{ if .AdditionalItems }} {{ if .AdditionalItems.Enum }} -var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []interface{} +var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []any func init() { var res []{{ template "dereffedSchemaType" .AdditionalItems }} @@ -1127,7 +1159,7 @@ func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else {{ end }} {{ with .AdditionalProperties }} {{ if .Enum }} -var {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum []interface{} +var {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum []any func init() { var res []{{ template "dereffedSchemaType" . }} if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil { @@ -1169,7 +1201,7 @@ func ({{.ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else i {{ if .HasAdditionalItems }} {{ if .AdditionalItems.Enum }} -var {{ camelize .Name }}ItemsEnum []interface{} +var {{ camelize .Name }}ItemsEnum []any func init() { var res []{{ template "dereffedSchemaType" .AdditionalItems }} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/serializers/additionalpropertiesserializer.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/serializers/additionalpropertiesserializer.gotmpl index a09058683..8abad384b 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/serializers/additionalpropertiesserializer.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/serializers/additionalpropertiesserializer.gotmpl @@ -13,7 +13,7 @@ func ({{.ReceiverName}} *{{ pascalize .Name }}) UnmarshalJSON(data []byte) error *{{ .ReceiverName }} = rcv // stage 2, remove properties and add to map - stage2 := make(map[string]{{ if .AdditionalProperties }}json.RawMessage{{ else }}interface{}{{ end }}) + stage2 := make(map[string]{{ if .AdditionalProperties }}json.RawMessage{{ else }}any{{ end }}) if err := json.Unmarshal(data, &stage2); err != nil { return err } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/serializers/subtypeserializer.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/serializers/subtypeserializer.gotmpl index b15613efc..819e67ff1 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/serializers/subtypeserializer.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/serializers/subtypeserializer.gotmpl @@ -28,14 +28,14 @@ func ({{.ReceiverName}} *{{ pascalize .Name }}) UnmarshalJSON(raw []byte) error var allOf{{ pascalize .Name }} {{ if .IsArray }}[]{{ pascalize .Items.GoType }}{{ else }}{{ pascalize .GoType }}{{ end }} if string(data.{{ pascalize .Name }}) != "null" { {{ camelize .Name }}, err := Unmarshal{{ if .IsArray }}{{ pascalize .Items.GoType }}Slice{{ else }}{{ pascalize .GoType }}{{ end }}(bytes.NewBuffer(data.{{ pascalize .Name }}), runtime.JSONConsumer()) - if err != nil && err != io.EOF { + if err != nil && !stderrors.Is(err, io.EOF) { return err } allOf{{ pascalize .Name }} = {{ camelize .Name }} } {{- else }} allOf{{ pascalize .Name }}, err := Unmarshal{{ if .IsArray }}{{ pascalize .Items.GoType }}Slice{{ else }}{{ pascalize .GoType }}{{ end }}(bytes.NewBuffer(data.{{ pascalize .Name }}), runtime.JSONConsumer()) - if err != nil && err != io.EOF { + if err != nil && !stderrors.Is(err, io.EOF) { return err } {{- end }} @@ -49,14 +49,14 @@ func ({{.ReceiverName}} *{{ pascalize .Name }}) UnmarshalJSON(raw []byte) error var prop{{ pascalize .Name }} {{ if .IsArray }}[]{{ pascalize .Items.GoType }}{{ else }}{{ pascalize .GoType }}{{ end }} if string(data.{{ pascalize .Name }}) != "null" { {{ camelize .Name }}, err := Unmarshal{{ if .IsArray }}{{ pascalize .Items.GoType }}Slice{{ else }}{{ pascalize .GoType }}{{ end }}(bytes.NewBuffer(data.{{ pascalize .Name }}), runtime.JSONConsumer()) - if err != nil && err != io.EOF { + if err != nil && !stderrors.Is(err, io.EOF) { return err } prop{{ pascalize .Name }} = {{ camelize .Name }} } {{- else }} prop{{ pascalize .Name }}, err := Unmarshal{{ if .IsArray }}{{ pascalize .Items.GoType }}Slice{{ else }}{{ pascalize .GoType }}{{ end }}(bytes.NewBuffer(data.{{ pascalize .Name }}), runtime.JSONConsumer()) - if err != nil && err != io.EOF { + if err != nil && !stderrors.Is(err, io.EOF) { return err } {{- end }} @@ -119,7 +119,7 @@ func ({{.ReceiverName}} *{{ pascalize .Name }}) UnmarshalJSON(raw []byte) error {{ if .IsAdditionalProperties }} // Additional Properties: read raw, remove named properties, and add to map - rawProps := make(map[string]{{ if .AdditionalProperties }}json.RawMessage{{ else }}interface{}{{ end }}) + rawProps := make(map[string]{{ if .AdditionalProperties }}json.RawMessage{{ else }}any{{ end }}) if err := json.Unmarshal(raw, &rawProps); err != nil { return err } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/serializers/tupleserializer.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/serializers/tupleserializer.gotmpl index c05e844bb..c493b766f 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/serializers/tupleserializer.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/serializers/tupleserializer.gotmpl @@ -51,7 +51,7 @@ func ({{.ReceiverName}} *{{ pascalize .Name }}) UnmarshalJSON(raw []byte) error // MarshalJSON marshals this tuple type into a JSON array func ({{.ReceiverName}} {{ pascalize .Name }}) MarshalJSON() ([]byte, error) { - data := []interface{}{ + data := []any{ {{ range .Properties -}} {{.ReceiverName}}.{{ pascalize .Name }}, {{- end }} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/autoconfigureapi.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/autoconfigureapi.gotmpl index 629b4b22b..77cc1ec3b 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/autoconfigureapi.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/autoconfigureapi.gotmpl @@ -42,12 +42,13 @@ import ( {{- if .ExcludeSpec }} --exclude-spec{{ end }} {{- if .DumpData }} --dump-data{{ end }} {{- if .StrictResponders }} --strict-responders{{ end }} +{{- if .ReturnErrors }} --return-errors{{ end }} {{ end }} // This file auto configures the api backend implementation. // {{.ImplementationPackageAlias}} package must already exist. // {{.ImplementationPackageAlias}}.New() is implemented by user, and must return an object -// or interface that implements Handler interface defined below. +// or interface that implements Handler interface defined below. var Impl Handler = {{.ImplementationPackageAlias}}.New() // Handler handles all api server backend configurations and requests @@ -77,7 +78,7 @@ type Authable interface{ {{- range .SecurityDefinitions }} {{- if .IsBasicAuth }} // Applies when the Authorization header is set with the Basic scheme - {{ pascalize .ID }}Auth(user string, pass string) ({{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) + {{ pascalize .ID }}Auth(user string, password string) ({{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) {{- else if .IsAPIKeyAuth }} // Applies when the "{{ .Name }}" {{ .Source }} is set {{ pascalize .ID }}Auth(token string) ({{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) @@ -101,7 +102,11 @@ type {{ pascalize .Name }}Handler interface { {{ end -}} {{ pascalize .Name }}(params {{ if ne .Package $package }}{{ .PackageAlias }}{{ else }}{{- $apipackagealias }}{{ end }}. {{- pascalize .Name }}Params {{- if .Authorized}}, principal {{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}{{end}}) - {{- if $.GenOpts.StrictResponders }} {{.Package}}.{{ pascalize .Name }}Responder {{ else }} middleware.Responder {{ end }} + {{- if $.GenOpts.ReturnErrors }} + {{- if $.GenOpts.StrictResponders }} ({{.Package}}.{{ pascalize .Name }}Responder, error) {{ else }} (middleware.Responder, error) {{ end }} + {{ else }} + {{- if $.GenOpts.StrictResponders }} {{.Package}}.{{ pascalize .Name }}Responder {{ else }} middleware.Responder {{ end }} + {{ end -}} {{ end -}} } {{ end }} @@ -120,7 +125,7 @@ func configureAPI(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) http.Handl {{- if .Implementation }} api.{{ pascalize .Name }}Consumer = {{ .Implementation }} {{- else }} - api.{{ pascalize .Name }}Consumer = runtime.ConsumerFunc(func(r io.Reader, target interface{}) error { + api.{{ pascalize .Name }}Consumer = runtime.ConsumerFunc(func(r io.Reader, target any) error { return Impl.{{ pascalize .Name }}Consume(r, target) }) {{- end }} @@ -129,7 +134,7 @@ func configureAPI(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) http.Handl {{- if .Implementation }} api.{{ pascalize .Name }}Producer = {{ .Implementation }} {{- else }} - api.{{ pascalize .Name }}Producer = runtime.ProducerFunc(func(w io.Writer, data interface{}) error { + api.{{ pascalize .Name }}Producer = runtime.ProducerFunc(func(w io.Writer, data any) error { return Impl.{{ pascalize .Name }}Produce(w, target) }) {{- end }} @@ -137,10 +142,10 @@ func configureAPI(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) http.Handl {{ range .SecurityDefinitions }} {{- if .IsBasicAuth }} // Applies when the Authorization header is set with the Basic scheme - api.{{ pascalize .ID }}Auth = func(user string, pass string) ({{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { - return Impl.{{ pascalize .ID }}Auth(user, pass) + api.{{ pascalize .ID }}Auth = func(user string, password string) ({{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { + return Impl.{{ pascalize .ID }}Auth(user, password) } - + {{- else if .IsAPIKeyAuth }} // Applies when the "{{ .Name }}" {{ .Source }} is set api.{{ pascalize .ID }}Auth = func(token string) ({{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { @@ -162,8 +167,12 @@ func configureAPI(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) http.Handl {{- else }} {{- $apipackagealias }}.{{- pascalize .Name }}HandlerFunc(func(params {{ $apipackagealias }}.{{- pascalize .Name }}Params {{- end }} - {{- if .Authorized}}, principal {{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}{{end}}) - {{- if $.GenOpts.StrictResponders }} {{.Package}}.{{ pascalize .Name }}Responder { {{ else }} middleware.Responder { {{ end }} + {{- if .Authorized}}, principal {{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}{{end}}) + {{- if $.GenOpts.ReturnErrors }} + {{- if $.GenOpts.StrictResponders }} ({{.Package}}.{{ pascalize .Name }}Responder, error) { {{ else }} (middleware.Responder, error) { {{ end }} + {{ else }} + {{- if $.GenOpts.StrictResponders }} {{.Package}}.{{ pascalize .Name }}Responder { {{ else }} middleware.Responder { {{ end }} + {{ end }} return Impl.{{ pascalize .Name }}(params {{- if .Authorized}}, principal {{ end }}) }) {{- end }} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/builder.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/builder.gotmpl index fda11859a..a290a18a1 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/builder.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/builder.gotmpl @@ -51,7 +51,10 @@ func New{{ pascalize .Name }}API(spec *loads.Document) *{{ pascalize .Name }}API {{- if .Implementation }} {{ pascalize .Name }}Consumer: {{ .Implementation }}, {{- else }} - {{ pascalize .Name }}Consumer: runtime.ConsumerFunc(func(r io.Reader, target interface{}) error { + {{ pascalize .Name }}Consumer: runtime.ConsumerFunc(func(r io.Reader, target any) error { + _ = r + _ = target + return errors.NotImplemented("{{.Name}} consumer has not yet been implemented") }), {{- end }} @@ -60,38 +63,62 @@ func New{{ pascalize .Name }}API(spec *loads.Document) *{{ pascalize .Name }}API {{- if .Implementation }} {{ pascalize .Name }}Producer: {{ .Implementation }}, {{- else }} - {{ pascalize .Name }}Producer: runtime.ProducerFunc(func(w io.Writer, data interface{}) error { + {{ pascalize .Name }}Producer: runtime.ProducerFunc(func(w io.Writer, data any) error { + _ = w + _ = data + return errors.NotImplemented("{{.Name}} producer has not yet been implemented") }), {{- end }} {{- end }} {{ range .Operations }} + {{ $mayBePackage := "" }} + {{ if ne .Package $package -}} + {{ $mayBePackage = printf "%s." .PackageAlias }} + {{ end -}} + {{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler: - {{- if ne .Package $package }}{{ .PackageAlias }}.{{ end }}{{ pascalize .Name }}HandlerFunc(func(params {{ if ne .Package $package }}{{ .PackageAlias }}.{{end }} - {{- if $.GenOpts.StrictResponders}} - {{- pascalize .Name }}Params{{if .Authorized}}, principal {{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}{{end}}) {{if ne .Package $package }}{{ .Package }}.{{ end }}{{ pascalize .Name }}Responder { - return {{if ne .Package $package }}{{ .Package }}.{{ end }}{{ pascalize .Name }}NotImplemented() - {{else}} - {{- pascalize .Name }}Params{{if .Authorized}}, principal {{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}{{end}}) middleware.Responder { - return middleware.NotImplemented("operation {{ if ne .Package $package }}{{ .Package }}.{{ end }}{{pascalize .Name}} has not yet been implemented") - {{ end -}} + {{ $mayBePackage }}{{ pascalize .Name }}HandlerFunc(func(params {{ $mayBePackage }}{{ pascalize .Name }}Params{{if .Authorized}}, principal {{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}{{end}}) + {{- if $.GenOpts.ReturnErrors }} + {{- if $.GenOpts.StrictResponders }} ({{ $mayBePackage }}{{ pascalize .Name }}Responder, error) { {{ else }} (middleware.Responder, error) { {{ end }} + {{ else }} + {{- if $.GenOpts.StrictResponders }} {{ $mayBePackage }}{{ pascalize .Name }}Responder { {{ else }} middleware.Responder { {{ end }} + {{ end -}} + _ = params + {{- if .Authorized }} + _ = principal + {{- end }} + + {{ if $.GenOpts.StrictResponders }} + return {{ $mayBePackage }}{{ pascalize .Name }}NotImplemented(){{ if $.GenOpts.ReturnErrors }}, nil {{- end -}} + {{ else }} + return middleware.NotImplemented("operation {{ $mayBePackage }}{{pascalize .Name}} has not yet been implemented"){{ if $.GenOpts.ReturnErrors }}, nil {{- end -}} + {{- end }} }), {{- end }} {{ range .SecurityDefinitions }} {{- if .IsBasicAuth }} // Applies when the Authorization header is set with the Basic scheme - {{ pascalize .ID }}Auth: func(user string, pass string) ({{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { + {{ pascalize .ID }}Auth: func(user string, password string) ({{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { + _ = user + _ = password + return nil, errors.NotImplemented("basic auth ({{ .ID }}) has not yet been implemented") }, {{- end }} {{- if .IsAPIKeyAuth }} // Applies when the "{{ .Name }}" {{ .Source }} is set {{ pascalize .ID }}Auth: func(token string) ({{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { + _ = token + return nil, errors.NotImplemented("api key auth ({{ .ID }}) {{.Name}} from {{.Source}} param [{{ .Name }}] has not yet been implemented") }, {{- end }} {{- if .IsOAuth2 }} {{ pascalize .ID }}Auth: func(token string, scopes []string) ({{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { + _ = token + _ = scopes + return nil, errors.NotImplemented("oauth2 bearer auth ({{ .ID }}) has not yet been implemented") }, {{- end }} @@ -188,7 +215,7 @@ type {{ pascalize .Name }}API struct { CommandLineOptionsGroups []swag.CommandLineOptionsGroup // User defined logger function. - Logger func(string, ...interface{}) + Logger func(string, ...any) } // UseRedoc for documentation at /docs @@ -266,37 +293,51 @@ func ({{.ReceiverName}} *{{ pascalize .Name }}API) Validate() error { return nil } + // ServeErrorFor gets a error handler for a given operation id func ({{.ReceiverName}} *{{ pascalize .Name }}API) ServeErrorFor(operationID string) func(http.ResponseWriter, *http.Request, error) { return {{.ReceiverName}}.ServeError } +{{- define "defForScheme" }} + {{- if .IsBasicAuth }} + result[name] = {{.ReceiverName}}.BasicAuthenticator({{ if not ( eq .Principal "any" ) }}func(username, password string) (any, error) { + return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "any" ) }}(username, password) + }{{ end }}) + {{- else if .IsAPIKeyAuth }} + scheme := schemes[name] + result[name] = {{.ReceiverName}}.APIKeyAuthenticator(scheme.Name, scheme.In, {{ if not ( eq .Principal "any" ) }}func(token string) (any, error) { + return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "any" ) }}(token) + }{{ end }}) + {{- else if .IsOAuth2 }} + result[name] = {{.ReceiverName}}.BearerAuthenticator(name, {{ if not ( eq .Principal "any" ) }}func(token string, scopes []string) (any, error) { + return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "any" ) }}(token, scopes) + }{{ end }}) + {{- end }} +{{- end }} + // AuthenticatorsFor gets the authenticators for the specified security schemes func ({{.ReceiverName}} *{{ pascalize .Name }}API) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator { {{- if .SecurityDefinitions }} result := make(map[string]runtime.Authenticator) for name := range schemes { + {{- if gt (len .SecurityDefinitions) 1 }} switch name { {{- range .SecurityDefinitions }} case "{{.ID}}": - {{- if .IsBasicAuth }} - result[name] = {{.ReceiverName}}.BasicAuthenticator({{ if not ( eq .Principal "interface{}" ) }}func(username, password string) (interface{}, error) { - return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "interface{}" ) }}(username, password) - }{{ end }}) - {{- end }} - {{- if .IsAPIKeyAuth }} - scheme := schemes[name] - result[name] = {{.ReceiverName}}.APIKeyAuthenticator(scheme.Name, scheme.In, {{ if not ( eq .Principal "interface{}" ) }}func(token string) (interface{}, error) { - return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "interface{}" ) }}(token) - }{{ end }}) - {{- end }} - {{- if .IsOAuth2 }} - result[name] = {{.ReceiverName}}.BearerAuthenticator(name, {{ if not ( eq .Principal "interface{}" ) }}func(token string, scopes []string) (interface{}, error) { - return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "interface{}" ) }}(token, scopes) - }{{ end }}) - {{- end }} - {{end}} + {{- template "defForScheme" . }} + {{ end }} + } + {{- else }} + {{- /* whenever we only have one security definition, write this as a if statement rather than a switch */}} + {{- $definition := (index .SecurityDefinitions 0) }} + {{- with $definition }} + if name == "{{ .ID }}" { + {{- template "defForScheme" . }} } + {{- end }} + {{- end }} } + return result {{- else }} return nil @@ -313,24 +354,37 @@ func ({{.ReceiverName}} *{{ pascalize .Name }}API) Authorizer() runtime.Authoriz } // ConsumersFor gets the consumers for the specified media types. +// // MIME type parameters are ignored here. func ({{.ReceiverName}} *{{ pascalize .Name }}API) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer { {{- if .Consumes }} result := make(map[string]runtime.Consumer, len(mediaTypes)) for _, mt := range mediaTypes { + {{- if gt .Consumes.NumSerializers 1 }} switch mt { - {{- range .Consumes }} - {{- range .AllSerializers }} + {{- range .Consumes }} + {{- range .AllSerializers }} case "{{ .MediaType }}": result["{{ .MediaType }}"] = {{.ReceiverName}}.{{ pascalize .Name }}Consumer + {{- end }} {{- end }} - {{- end }} } + {{- else }} + {{- /* whenever we only have one serializer, write this as a if statement rather than a switch */}} + {{- $serializerGroup := (index .Consumes 0) }} + {{- $serializer := (index $serializerGroup.AllSerializers 0) }} + {{- with $serializer }} + if mt == "{{ .MediaType }}" { + result["{{ .MediaType }}"] = {{.ReceiverName}}.{{ pascalize .Name }}Consumer + } + {{- end }} + {{- end }} if c, ok := {{.ReceiverName}}.customConsumers[mt]; ok { result[mt] = c } } + return result {{- else }} return nil @@ -338,11 +392,13 @@ func ({{.ReceiverName}} *{{ pascalize .Name }}API) ConsumersFor(mediaTypes []str } // ProducersFor gets the producers for the specified media types. +// // MIME type parameters are ignored here. func ({{.ReceiverName}} *{{ pascalize .Name }}API) ProducersFor(mediaTypes []string) map[string]runtime.Producer { {{- if .Produces }} result := make(map[string]runtime.Producer, len(mediaTypes)) for _, mt := range mediaTypes { + {{- if gt .Produces.NumSerializers 1 }} switch mt { {{- range .Produces }} {{- range .AllSerializers }} @@ -351,11 +407,22 @@ func ({{.ReceiverName}} *{{ pascalize .Name }}API) ProducersFor(mediaTypes []str {{- end }} {{- end }} } + {{- else }} + {{- /* whenever we only have one serializer, write this as a if statement rather than a switch */}} + {{- $serializerGroup := (index .Produces 0) }} + {{- $serializer := (index $serializerGroup.AllSerializers 0) }} + {{- with $serializer }} + if mt == "{{ .MediaType }}" { + result["{{ .MediaType }}"] = {{.ReceiverName}}.{{ pascalize .Name }}Producer + } + {{- end }} + {{- end }} if p, ok := {{.ReceiverName}}.customProducers[mt]; ok { result[mt] = p } } + return result {{- else }} return nil diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/configureapi.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/configureapi.gotmpl index cbbb0bfd1..7d8167d95 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/configureapi.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/configureapi.gotmpl @@ -40,9 +40,11 @@ import ( {{- if .ExcludeSpec }} --exclude-spec{{ end }} {{- if .DumpData }} --dump-data{{ end }} {{- if .StrictResponders }} --strict-responders{{ end }} +{{- if .ReturnErrors }} --return-errors{{ end }} {{ end }} func configureFlags(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) { // api.CommandLineOptionsGroups = []swag.CommandLineOptionsGroup{ ... } + _ = api } func configureAPI(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) http.Handler { @@ -50,7 +52,7 @@ func configureAPI(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) http.Handl api.ServeError = errors.ServeError // Set your custom logger if needed. Default one is log.Printf - // Expected interface func(string, ...interface{}) + // Expected interface func(string, ...any) // // Example: // api.Logger = log.Printf @@ -63,7 +65,10 @@ func configureAPI(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) http.Handl {{- if .Implementation }} api.{{ pascalize .Name }}Consumer = {{ .Implementation }} {{- else }} - api.{{ pascalize .Name }}Consumer = runtime.ConsumerFunc(func(r io.Reader, target interface{}) error { + api.{{ pascalize .Name }}Consumer = runtime.ConsumerFunc(func(r io.Reader, target any) error { + _ = r + _ = target + return errors.NotImplemented("{{.Name}} consumer has not yet been implemented") }) {{- end }} @@ -72,7 +77,10 @@ func configureAPI(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) http.Handl {{- if .Implementation }} api.{{ pascalize .Name }}Producer = {{ .Implementation }} {{- else }} - api.{{ pascalize .Name }}Producer = runtime.ProducerFunc(func(w io.Writer, data interface{}) error { + api.{{ pascalize .Name }}Producer = runtime.ProducerFunc(func(w io.Writer, data any) error { + _ = w + _ = data + return errors.NotImplemented("{{.Name}} producer has not yet been implemented") }) {{- end }} @@ -81,7 +89,10 @@ func configureAPI(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) http.Handl {{- if .IsBasicAuth }} // Applies when the Authorization header is set with the Basic scheme if api.{{ pascalize .ID }}Auth == nil { - api.{{ pascalize .ID }}Auth = func(user string, pass string) ({{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { + api.{{ pascalize .ID }}Auth = func(user string, password string) ({{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { + _ = user + _ = password + return nil, errors.NotImplemented("basic auth ({{ .ID }}) has not yet been implemented") } } @@ -89,12 +100,17 @@ func configureAPI(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) http.Handl // Applies when the "{{ .Name }}" {{ .Source }} is set if api.{{ pascalize .ID }}Auth == nil { api.{{ pascalize .ID }}Auth = func(token string) ({{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { + _ = token + return nil, errors.NotImplemented("api key auth ({{ .ID }}) {{.Name}} from {{.Source}} param [{{ .Name }}] has not yet been implemented") } } {{- else if .IsOAuth2 }} if api.{{ pascalize .ID }}Auth == nil { api.{{ pascalize .ID }}Auth = func(token string, scopes []string) ({{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}, error) { + _ = token + _ = scopes + return nil, errors.NotImplemented("oauth2 bearer auth ({{ .ID }}) has not yet been implemented") } } @@ -124,13 +140,22 @@ func configureAPI(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) http.Handl {{- else }} {{- $apipackagealias }}.{{- pascalize .Name }}HandlerFunc(func(params {{ $apipackagealias }}.{{- pascalize .Name }}Params {{- end }} - {{- if $.GenOpts.StrictResponders }} - {{- if .Authorized}}, principal {{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}{{end}}) {{.Package}}.{{ pascalize .Name }}Responder { - return {{.Package}}.{{ pascalize .Name }}NotImplemented() - {{ else }} - {{- if .Authorized}}, principal {{if .PrincipalIsNullable }}*{{ end }}{{.Principal}}{{end}}) middleware.Responder { - return middleware.NotImplemented("operation {{ .Package}}.{{pascalize .Name}} has not yet been implemented") - {{ end -}} + {{- if .Authorized}}, principal {{ if .PrincipalIsNullable }}*{{ end }}{{.Principal}}{{end}}) + {{- if $.GenOpts.ReturnErrors }} + {{- if $.GenOpts.StrictResponders }} ({{.Package}}.{{ pascalize .Name }}Responder, error) { {{ else }} (middleware.Responder, error) { {{ end }} + {{ else }} + {{- if $.GenOpts.StrictResponders }} {{.Package}}.{{ pascalize .Name }}Responder { {{ else }} middleware.Responder { {{ end }} + {{ end -}} + _ = params + {{- if .Authorized }} + _ = principal + {{- end }} + + {{ if $.GenOpts.StrictResponders }} + return {{.Package}}.{{ pascalize .Name }}NotImplemented(){{ if $.GenOpts.ReturnErrors }}, nil {{- end -}} + {{ else }} + return middleware.NotImplemented("operation {{ .Package}}.{{pascalize .Name}} has not yet been implemented"){{ if $.GenOpts.ReturnErrors }}, nil {{- end -}} + {{- end }} }) } {{- end }} @@ -145,13 +170,17 @@ func configureAPI(api *{{.APIPackageAlias}}.{{ pascalize .Name }}API) http.Handl // The TLS configuration before HTTPS server starts. func configureTLS(tlsConfig *tls.Config) { // Make all necessary changes to the TLS configuration here. + _ = tlsConfig } // As soon as server is initialized but not run yet, this function will be called. // If you need to modify a config, store server instance to stop it individually later, this is the place. // This function can be called multiple times, depending on the number of serving schemes. // scheme value will be set accordingly: "http", "https" or "unix". -func configureServer(s *http.Server, scheme, addr string) { +func configureServer(server *http.Server, scheme, addr string) { + _ = server + _ = scheme + _ = addr } // The middleware configuration is for the handler executors. These do not apply to the swagger.json document. diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/main.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/main.gotmpl index a6447ede7..4e9b86632 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/main.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/main.gotmpl @@ -1,12 +1,93 @@ -// Code generated by go-swagger; DO NOT EDIT. +{{- define "specTitle" }} + {{- if .Info }} + {{- if .Info.Title }} + {{- printf "%q" .Info.Title }} + {{- else }} + {{- if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Title{{ end }} + {{- end }} + {{- else }} + {{- if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Title{{ end }} + {{- end}} +{{- end }} + +{{- define "specDescription" }} + {{- if .Info }} + {{- if .Info.Description }} + {{- printf "%q" .Info.Description }} + {{- else }} + {{- if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Description{{ end }} + {{- end }} + {{- else }} + {{- if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Description{{ end }} + {{- end}} +{{- end }} + +{{- define "printUsage" }} fmt.Fprint(os.Stderr, "Usage:\n") + fmt.Fprint(os.Stderr, " {{ dasherize .Name }}-server [OPTIONS]\n\n") + + title := {{ template "specTitle" . }} + if title != "" { + fmt.Fprintf(os.Stderr, "%s\n\n", title) + } + desc := {{ template "specDescription" . }} + if desc != "" { + fmt.Fprintf(os.Stderr, "%s\n\n", desc) + } +{{- end }} + +{{- define "argsParser" }} + {{- if .UsePFlags }}{{/* CLI flags by github.com/spf13/pflag */}} + flag.Usage = func() { + {{ template "printUsage" . }} + fmt.Fprintln(os.Stderr, flag.CommandLine.FlagUsages()) + } + + // parse the CLI flags + flag.Parse() // exit on error + {{- else if .UseGoStructFlags }}{{/* CLI flags by github.com/jessevdk/go-flags */}} + parser := flags.NewParser(server, flags.Default) + parser.ShortDescription = {{ template "specTitle" . }} + parser.LongDescription = {{ template "specDescription" . }} + {{- if not .ExcludeSpec }} + for _, optsGroup := range api.CommandLineOptionsGroups { + _, err := parser.AddGroup(optsGroup.ShortDescription, optsGroup.LongDescription, optsGroup.Options) + if err != nil { + log.Fatalln(err) + } + } + {{- end }} + if _, err := parser.Parse(); err != nil { + code := 1 + fe := new(flags.Error) + if errors.As(err, &fe) { + if fe.Type == flags.ErrHelp { + code = 0 + } + } + os.Exit(code) + } + {{- else if .UseFlags }}{{/* CLI flags by standard library */}} + flag.Usage = func() { + {{ template "printUsage" . }} + flag.CommandLine.SetOutput(os.Stderr) + flag.PrintDefaults() + } - {{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} + // parse the CLI flags + flag.Parse() // exit on error + {{- else }} + // missing a CLI flag library setting + {{- end }} +{{- end }} +// Code generated by go-swagger; DO NOT EDIT. +{{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }} package main import ( + "errors" "fmt" "log" "net/http" @@ -15,12 +96,12 @@ import ( "github.com/go-openapi/loads" {{- if .UseGoStructFlags }} flags "github.com/jessevdk/go-flags" - {{- end }} - {{- if .UsePFlags }} + {{- else if .UsePFlags }} flag "github.com/spf13/pflag" - {{- end }} - {{- if .UseFlags }} + {{- else if .UseFlags }} "flag" + {{- else }} + // missing a CLI flag library setting {{- end }} {{ imports .DefaultImports }} @@ -29,63 +110,21 @@ import ( // This file was generated by the swagger tool. // Make sure not to overwrite this file after you generated it because all your edits would be lost! -{{ if .ExcludeSpec }} +{{- if .ExcludeSpec }}{{/* spec excluded means that it is not built inside the generated code and loaded at runtime */}} + func init() { loads.AddLoader(fmts.YAMLMatcher, fmts.YAMLDoc) } -{{ end }} +{{- end }} func main() { - {{ if .UsePFlags }} - {{- if not .ExcludeSpec }} - swaggerSpec, err := loads.Embedded({{ .ServerPackageAlias }}.SwaggerJSON, {{ .ServerPackageAlias }}.FlatSwaggerJSON) - if err != nil { - log.Fatalln(err) - } - {{- end }} - - var server *{{ .ServerPackageAlias }}.Server // make sure init is called - - flag.Usage = func() { - fmt.Fprint(os.Stderr, "Usage:\n") - fmt.Fprint(os.Stderr, " {{ dasherize .Name }}-server [OPTIONS]\n\n") - - title := {{ if .Info }}{{ if .Info.Title }}{{ printf "%q" .Info.Title }}{{ else }}{{ if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Title{{ end }}{{ end }}{{ else }}{{ if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Title{{ end }}{{ end}} - fmt.Fprint(os.Stderr, title+"\n\n") - desc := {{ if .Info }}{{ if .Info.Description }}{{ printf "%q" .Info.Description }}{{ else }}{{ if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Description{{ end }}{{ end }}{{ else }}{{ if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Description{{ end }}{{ end}} - if desc != "" { - fmt.Fprintf(os.Stderr, desc+"\n\n") - } - fmt.Fprintln(os.Stderr, flag.CommandLine.FlagUsages()) - } - // parse the CLI flags - flag.Parse() - {{- if .ExcludeSpec }} - - server = {{ .ServerPackageAlias }}.NewServer(nil) - swaggerSpec, err := loads.Spec(string(server.Spec)) - if err != nil { - log.Fatalln(err) - } - api := {{.APIPackageAlias}}.New{{ pascalize .Name }}API(swaggerSpec) - server.SetAPI(api) - {{- else }} - - api := {{.APIPackageAlias}}.New{{ pascalize .Name }}API(swaggerSpec) - // get server with flag values filled out - server = {{ .ServerPackageAlias }}.NewServer(api) - {{- end }} - defer server.Shutdown() - - server.ConfigureAPI() - if err := server.Serve(); err != nil { - log.Fatalln(err) - } - {{ end }} - {{ if .UseGoStructFlags}} - {{- if .ExcludeSpec }} +{{- if .ExcludeSpec }} + {{- if not .UseGoStructFlags }}{{/* with pflag and flag, an init() func injects args */}} + var server *{{ .ServerPackageAlias }}.Server + {{- else }} server := {{ .ServerPackageAlias }}.NewServer(nil) - {{- else }} + {{- end }} +{{- else }} swaggerSpec, err := loads.Embedded({{ .ServerPackageAlias }}.SwaggerJSON, {{ .ServerPackageAlias }}.FlatSwaggerJSON) if err != nil { log.Fatalln(err) @@ -93,94 +132,34 @@ func main() { api := {{.APIPackageAlias}}.New{{ pascalize .Name }}API(swaggerSpec) server := {{ .ServerPackageAlias }}.NewServer(api) - defer server.Shutdown() - {{- end }} - - parser := flags.NewParser(server, flags.Default) - parser.ShortDescription = {{ if .Info }}{{ if .Info.Title }}{{ printf "%q" .Info.Title }}{{ else }}{{ if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Title{{ end }}{{ end }}{{ else }}{{ if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Title{{ end }}{{ end}} - parser.LongDescription = {{ if .Info }}{{ if .Info.Description }}{{ printf "%q" .Info.Description }}{{ else }}{{ if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Description{{ end }}{{ end }}{{ else }}{{ if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Description{{ end }}{{ end}} - - {{- if not .ExcludeSpec }} - server.ConfigureFlags() - for _, optsGroup := range api.CommandLineOptionsGroups { - _, err := parser.AddGroup(optsGroup.ShortDescription, optsGroup.LongDescription, optsGroup.Options) - if err != nil { - log.Fatalln(err) - } - } - {{- end }} - - if _, err := parser.Parse(); err != nil { - code := 1 - if fe, ok := err.(*flags.Error); ok { - if fe.Type == flags.ErrHelp { - code = 0 - } - } - os.Exit(code) - } - {{- if .ExcludeSpec }} - swaggerSpec, err := loads.Spec(string(server.Spec)) - if err != nil { - log.Fatalln(err) - } - - api := {{.APIPackageAlias}}.New{{ pascalize .Name }}API(swaggerSpec) - server.SetAPI(api) - defer server.Shutdown() - {{- end }} + server.ConfigureFlags() // inject API-specific custom flags. Must be called before args parsing +{{- end }} - server.ConfigureAPI() +{{ template "argsParser" . }} - if err := server.Serve(); err != nil { - log.Fatalln(err) - } - {{ end }} - {{ if .UseFlags}} - {{- if not .ExcludeSpec }} +{{- if .ExcludeSpec }}{{/* since the API is not loaded, we can't configure API-specific flags in this mode */}} + {{- if not .UseGoStructFlags }}{{/* with pflag and flag, args are retrieved using New */}} + server = {{ .ServerPackageAlias }}.NewServer(nil) // the server has no API set yet, but configuration from flags is retrieved at this point + {{- end }} - swaggerSpec, err := loads.Embedded({{ .ServerPackageAlias }}.SwaggerJSON, {{ .ServerPackageAlias }}.FlatSwaggerJSON) - if err != nil { - log.Fatalln(err) + // spec loaded at run time from the provided CLI flags + if server.Spec == "" { + log.Fatalln("a spec must be provided by the command line") } - {{- end }} - var server *{{ .ServerPackageAlias }}.Server // make sure init is called - flag.Usage = func() { - fmt.Fprint(os.Stderr, "Usage:\n") - fmt.Fprint(os.Stderr, " {{ dasherize .Name }}-server [OPTIONS]\n\n") - - title := {{ if .Info }}{{ if .Info.Title }}{{ printf "%q" .Info.Title }}{{ else }}{{ if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Title{{ end }}{{ end }}{{ else }}{{ if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Title{{ end }}{{ end}} - fmt.Fprint(os.Stderr, title+"\n\n") - desc := {{ if .Info }}{{ if .Info.Description }}{{ printf "%q" .Info.Description }}{{ else }}{{ if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Description{{ end }}{{ end }}{{ else }}{{ if .ExcludeSpec }}""{{ else }}swaggerSpec.Spec().Info.Description{{ end }}{{ end}} - if desc != "" { - fmt.Fprintf(os.Stderr, desc+"\n\n") - } - flag.CommandLine.SetOutput(os.Stderr) - flag.PrintDefaults() - } - // parse the CLI flags - flag.Parse() - - {{- if .ExcludeSpec }} - - server = {{ .ServerPackageAlias }}.NewServer(nil) - swaggerSpec, err := loads.Spec(string(server.Spec)) + swaggerSpec, err := loads.Spec({{ if .UseGoStructFlags }}string({{ end }}server.Spec{{ if .UseGoStructFlags }}){{ end }}) if err != nil { log.Fatalln(err) } api := {{.APIPackageAlias}}.New{{ pascalize .Name }}API(swaggerSpec) server.SetAPI(api) - {{- else }} - api := {{.APIPackageAlias}}.New{{ pascalize .Name }}API(swaggerSpec) - // get server with flag values filled out - server = {{ .ServerPackageAlias }}.NewServer(api) - {{- end }} - defer server.Shutdown() +{{- end }} + + server.ConfigureAPI() // configure handlers, routes and middleware - server.ConfigureAPI() if err := server.Serve(); err != nil { + _ = server.Shutdown() + log.Fatalln(err) } - {{ end }} } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/operation.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/operation.gotmpl index 041c00e44..d01d59acb 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/operation.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/operation.gotmpl @@ -11,6 +11,9 @@ package {{ .Package }} import ( "net/http" + {{- if .ExtraSchemas }} + stderrors "errors" + {{- end }} "github.com/go-openapi/errors" "github.com/go-openapi/runtime/middleware" @@ -24,16 +27,32 @@ import ( ) // {{ pascalize .Name }}HandlerFunc turns a function with the right signature into a {{ humanize .Name }} handler -type {{ pascalize .Name }}HandlerFunc func({{ pascalize .Name }}Params{{ if .Authorized }}, {{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}{{ end }}) {{ if $.StrictResponders }} {{ pascalize .Name }}Responder {{else}} middleware.Responder {{end}} +type {{ pascalize .Name }}HandlerFunc func({{ pascalize .Name }}Params{{ if .Authorized }}, {{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}{{ end }}) + {{- if $.ReturnErrors }} + {{- if $.StrictResponders }} ({{ pascalize .Name }}Responder, error) {{else}} (middleware.Responder, error) {{end}} + {{ else }} + {{- if $.StrictResponders }} {{ pascalize .Name }}Responder {{else}} middleware.Responder {{end}} + {{ end }} // Handle executing the request and returning a response -func (fn {{ pascalize .Name }}HandlerFunc) Handle(params {{ pascalize .Name }}Params{{ if .Authorized }}, principal {{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}{{ end }}) {{ if $.StrictResponders }} {{ pascalize .Name }}Responder {{else}} middleware.Responder {{end}} { +func (fn {{ pascalize .Name }}HandlerFunc) Handle(params {{ pascalize .Name }}Params{{ if .Authorized }}, principal {{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}{{ end }}) + {{- if $.ReturnErrors }} + {{- if $.StrictResponders }} ({{ pascalize .Name }}Responder, error) {{else}} (middleware.Responder, error) {{end}} { + {{ else }} + {{- if $.StrictResponders }} {{ pascalize .Name }}Responder {{else}} middleware.Responder {{end}} { + {{ end -}} + return fn(params{{ if .Authorized }}, principal{{ end }}) } // {{ pascalize .Name }}Handler interface for that can handle valid {{ humanize .Name }} params type {{ pascalize .Name }}Handler interface { - Handle({{ pascalize .Name }}Params{{ if .Authorized }}, {{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}{{ end }}) {{ if $.StrictResponders }} {{ pascalize .Name }}Responder {{else}} middleware.Responder {{end}} + Handle({{ pascalize .Name }}Params{{ if .Authorized }}, {{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}{{ end }}) + {{- if $.ReturnErrors }} + {{- if $.StrictResponders }} ({{ pascalize .Name }}Responder, error) {{else}} (middleware.Responder, error) {{end}} + {{ else }} + {{- if $.StrictResponders }} {{ pascalize .Name }}Responder {{else}} middleware.Responder {{end}} + {{ end }} } // New{{ pascalize .Name }} creates a new http.Handler for the {{ humanize .Name }} operation @@ -71,7 +90,7 @@ func ({{ .ReceiverName }} *{{ pascalize .Name }}) ServeHTTP(rw http.ResponseWrit } var principal {{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }} if uprinc != nil { - principal = {{ if eq .Principal "inferface{}" }}uprinc{{ else }}uprinc.({{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}) // this is really a {{ .Principal }}, I promise{{ end }} + principal = {{ if or (eq .Principal "inferface{}") (eq .Principal "any") }}uprinc{{ else }}uprinc.({{ if .PrincipalIsNullable }}*{{ end }}{{ .Principal }}) // this is really a {{ .Principal }}, I promise{{ end }} } {{ end }} if err := {{ .ReceiverName }}.Context.BindValidRequest(r, route, &Params); err != nil { // bind params @@ -79,7 +98,16 @@ func ({{ .ReceiverName }} *{{ pascalize .Name }}) ServeHTTP(rw http.ResponseWrit return } - res := {{ .ReceiverName }}.Handler.Handle(Params{{ if .Authorized }}, principal{{ end }}) // actually handle the request + {{ if $.ReturnErrors }} + res, err := {{ .ReceiverName }}.Handler.Handle(Params{{ if .Authorized }}, principal{{ end }}) // actually handle the request + if err != nil { + {{ .ReceiverName }}.Context.Respond(rw, r, route.Produces, route, err) + return + } + {{ else }} + res := {{ .ReceiverName }}.Handler.Handle(Params{{ if .Authorized }}, principal{{ end }}) // actually handle the request + {{ end }} + {{ .ReceiverName }}.Context.Respond(rw, r, route.Produces, route, res) } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/parameter.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/parameter.gotmpl index 1000a9f95..08f9e515c 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/parameter.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/parameter.gotmpl @@ -161,7 +161,7 @@ if err := validate.EnumCase( {{- .ValueExpression -}}{{- if .Child.IsCustomFormatter }}.String(){{ end -}} {{- end -}} {{- end -}}, - {{- printf "%#v" .Enum -}}, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil { + {{- printGoLiteral .Enum -}}, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil { return err } {{- end }} @@ -186,11 +186,15 @@ if err := validate.EnumCase( {{- else if and .IsComplexObject .HasValidations }}{{/* dedicated to nested body params */}} {{ varname .ValueExpression }} := {{ varname .ValueExpression }}V if err := {{ .ValueExpression }}.Validate(formats) ; err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName({{ .Path }}) - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName({{ .Path }}) + ve := new(errors.Validation) + if stderrors.As(err, &ve) { + return ve.ValidateName({{ path . }}) } + ce := new(errors.CompositeError) + if stderrors.As(err, &ce) { + return ce.ValidateName({{ path . }}) + } + return err } {{- else }} @@ -298,6 +302,7 @@ package {{ .Package }} // Editing this file might prove futile when you re-run the swagger generate command import ( + stderrors "errors" "fmt" "io" "net/http" @@ -339,15 +344,15 @@ func New{{ pascalize .Name }}Params() {{ pascalize .Name }}Params { {{ if .HasDefault -}} {{ if not .IsFileParam }}{{ varname .ID}}Default = {{- if and .IsPrimitive .IsCustomFormatter (not (stringContains .Zero "(\"" )) }}{{ .Zero }}{{/* strfmt type initializer requires UnmarshalText(), e.g. Date, Datetime, Duration */}} - {{- else if and .IsPrimitive .IsCustomFormatter (stringContains .Zero "(\"" ) }}{{.GoType}}({{- printf "%#v" .Default }}){{/* strfmt type initializer takes string */}} - {{- else if and .IsPrimitive (not .IsCustomFormatter) -}}{{.GoType}}({{- printf "%#v" .Default }}){{/* regular go primitive type initializer */}} + {{- else if and .IsPrimitive .IsCustomFormatter (stringContains .Zero "(\"" ) }}{{.GoType}}({{- printGoLiteral .Default }}){{/* strfmt type initializer takes string */}} + {{- else if and .IsPrimitive (not .IsCustomFormatter) -}}{{.GoType}}({{- printGoLiteral .Default }}){{/* regular go primitive type initializer */}} {{- else if .IsArray -}}{{- /* Do not initialize from possible defaults in nested arrays */ -}} {{- if and .Child.IsPrimitive .Child.IsCustomFormatter }}{{ .Zero }}{{/* initialization strategy with UnmarshalText() */}} {{- else if .Child.IsArray -}}{{ .Zero }}{{/* initialization strategy with json.Unmarshal() */}} {{- else if and .Child.IsPrimitive (not .Child.IsCustomFormatter) -}}{{.GoType}}{{- arrayInitializer .Default }}{{/* regular go primitive type initializer: simple slice initializer */}} - {{- else }}{{ printf "%#v" .Default }}{{/* all other cases (e.g. schema) [should not occur] */}} + {{- else }}{{ printGoLiteral .Default }}{{/* all other cases (e.g. schema) [should not occur] */}} {{- end }} - {{- else }}{{ printf "%#v" .Default }}{{/* case .Schema */}} + {{- else }}{{ printGoLiteral .Default }}{{/* case .Schema */}} {{- end }} {{- end }} {{- end }} @@ -378,11 +383,11 @@ func New{{ pascalize .Name }}Params() {{ pascalize .Name }}Params { // // swagger:parameters {{ .Name }} type {{ pascalize .Name }}Params struct { - // HTTP Request Object HTTPRequest *http.Request `json:"-"` + {{- range .Params }} - {{ range .Params }}/*{{ if .Description }}{{ blockcomment .Description }}{{ end }}{{ if .Required }} + /*{{ if .Description }}{{ blockcomment .Description }}{{ end }}{{ if .Required }} Required: true{{ end }}{{ if .Maximum }} Maximum: {{ if .ExclusiveMaximum }}< {{ end }}{{ .Maximum }}{{ end }}{{ if .Minimum }} Minimum: {{ if .ExclusiveMinimum }}> {{ end }}{{ .Minimum }}{{ end }}{{ if .MultipleOf }} @@ -395,10 +400,10 @@ type {{ pascalize .Name }}Params struct { Unique: true{{ end }}{{ if .Location }} In: {{ .Location }}{{ end }}{{ if .CollectionFormat }} Collection Format: {{ .CollectionFormat }}{{ end }}{{ if .HasDefault }} - Default: {{ printf "%#v" .Default }}{{ end }} + Default: {{ printGoLiteral .Default }}{{ end }} */ {{ if not .Schema }}{{ pascalize .ID }} {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) (not .IsStream) .IsNullable }}*{{ end }}{{.GoType}}{{ else }}{{ pascalize .Name }} {{ if and (not .Schema.IsBaseType) .IsNullable (not .Schema.IsStream) }}*{{ end }}{{.GoType}}{{ end }} - {{ end}} + {{- end}} } // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface @@ -409,19 +414,16 @@ func ({{ .ReceiverName }} *{{ pascalize .Name }}Params) BindRequest(r *http.Requ var res []error {{ .ReceiverName }}.HTTPRequest = r - {{- if .HasQueryParams }} - qs := runtime.Values(r.URL.Query()) {{- end }} - {{- if .HasFormParams }} if err := r.ParseMultipartForm({{ pascalize .Name }}MaxParseMemory); err != nil { - if err != http.ErrNotMultipart { - return errors.New(400,"%v",err) - } else if err := r.ParseForm(); err != nil { + if !stderrors.Is(err,http.ErrNotMultipart) { return errors.New(400,"%v",err) + } else if errParse := r.ParseForm(); errParse != nil { + return errors.New(400,"%v",errParse) } } {{- if .HasFormValueParams }} @@ -451,19 +453,24 @@ func ({{ .ReceiverName }} *{{ pascalize .Name }}Params) BindRequest(r *http.Requ {{- if .IsFileParam }} {{ camelize .Name }}, {{ camelize .Name }}Header, err := r.FormFile({{ .Path }}) - if err != nil {{ if .IsNullable }}&& err != http.ErrMissingFile{{ end }}{ - res = append(res, errors.New(400, "reading file %q failed: %v", {{ printf "%q" (camelize .Name) }}, err)) + if err != nil { {{- if .IsNullable }} - } else if err == http.ErrMissingFile { - // no-op for missing but optional file parameter + if !stderrors.Is(err, http.ErrMissingFile) { + res = append(res, errors.New(400, "reading file %q failed: %v", {{ printf "%q" (camelize .Name) }}, err)) + } + // no-op for missing but optional file parameter + {{- else }} + res = append(res, errors.New(400, "reading file %q failed: %v", {{ printf "%q" (camelize .Name) }}, err)) {{- end }} - } else if err := {{ .ReceiverName }}.bind{{ pascalize .ID }}({{ camelize .Name }}, {{ camelize .Name }}Header); err != nil { + } else { + if errBind := {{ .ReceiverName }}.bind{{ pascalize .ID }}({{ camelize .Name }}, {{ camelize .Name }}Header); errBind != nil { {{- if .Required }} - // Required: true + // Required: true {{- end }} - res = append(res, err) - } else { - {{ .ReceiverName }}.{{ pascalize .Name }} = &runtime.File{Data: {{ camelize .Name }}, Header: {{ camelize .Name }}Header} + res = append(res, errBind) + } else { + {{ .ReceiverName }}.{{ pascalize .Name }} = &runtime.File{Data: {{ camelize .Name }}, Header: {{ camelize .Name }}Header} + } } {{- else }} @@ -506,12 +513,14 @@ func ({{ .ReceiverName }} *{{ pascalize .Name }}Params) BindRequest(r *http.Requ {{- if .Schema.IsStream }} {{ .ReceiverName }}.{{ pascalize .Name }} = r.Body {{- else }} - defer r.Body.Close() + defer func() { + _ = r.Body.Close() + }() {{- if and .Schema.IsBaseType .Schema.IsExported }} body, err := {{ toPackageName .ModelsPackage }}.Unmarshal{{ dropPackage .GoType }}{{ if .IsArray }}Slice{{ end }}(r.Body, route.Consumer) if err != nil { {{- if .Required }} - if err == io.EOF { + if stderrors.Is(err,io.EOF) { err = errors.Required({{ .Path }}, {{ printf "%q" .Location }}, "") } {{- end }} @@ -520,7 +529,7 @@ func ({{ .ReceiverName }} *{{ pascalize .Name }}Params) BindRequest(r *http.Requ var body {{ .GoType }} if err := route.Consumer.Consume(r.Body, &body); err != nil { {{- if .Required }} - if err == io.EOF { + if stderrors.Is(err,io.EOF) { res = append(res, errors.Required({{ printf "%q" (camelize .Name) }}, {{ printf "%q" .Location }}, "")) } else { {{- end }} @@ -683,7 +692,7 @@ func ({{ .ReceiverName }} *{{ $className }}Params) bind{{ pascalize .ID }}(rawDa {{- if or (and (not .IsArray) .HasValidations) (and .IsArray .HasSliceValidations) }} -// validate{{ pascalize .ID }} carries on validations for parameter {{ .ID }} +// validate{{ pascalize .ID }} carries out validations for parameter {{ .ID }} func ({{ .ReceiverName }} *{{ $className }}Params) validate{{ pascalize .ID }}(formats strfmt.Registry) error { {{ template "propertyparamvalidator" . }} return nil diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/responses.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/responses.gotmpl index 1d844a890..39b3bea96 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/responses.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/responses.gotmpl @@ -71,7 +71,7 @@ type {{ pascalize .Name }} struct { Max Items: {{ .MaxItems }}{{ end }}{{ if .MinItems }} Min Items: {{ .MinItems }}{{ end }}{{ if .UniqueItems }} Unique: true{{ end }}{{ if .HasDefault }} - Default: {{ printf "%#v" .Default }}{{ end }} + Default: {{ printGoLiteral .Default }}{{ end }} */ {{ pascalize .Name }} {{ .GoType }} `json:"{{.Name}}{{ if not .Required }},omitempty{{ end }}{{ if .IsJSONString }},string{{ end }}"` {{ end }} @@ -105,15 +105,15 @@ if code <= 0 { {{ if .HasDefault -}} {{ varname .ID}}Default = {{- if and .IsPrimitive .IsCustomFormatter (not (stringContains .Zero "(\"" )) }}{{ .Zero }}{{/* strfmt type initializer requires UnmarshalText(), e.g. Date, Datetime, Duration */}} - {{- else if and .IsPrimitive .IsCustomFormatter (stringContains .Zero "(\"" ) }}{{.GoType}}({{- printf "%#v" .Default }}){{/* strfmt type initializer takes string */}} - {{- else if and .IsPrimitive (not .IsCustomFormatter) -}}{{.GoType}}({{- printf "%#v" .Default }}){{/* regular go primitive type initializer */}} + {{- else if and .IsPrimitive .IsCustomFormatter (stringContains .Zero "(\"" ) }}{{.GoType}}({{- printGoLiteral .Default }}){{/* strfmt type initializer takes string */}} + {{- else if and .IsPrimitive (not .IsCustomFormatter) -}}{{.GoType}}({{- printGoLiteral .Default }}){{/* regular go primitive type initializer */}} {{- else if .IsArray -}}{{- /* Do not initialize from possible defaults in nested arrays */ -}} {{- if and .Child.IsPrimitive .Child.IsCustomFormatter }}{{ .Zero }}{{/* initialization strategy with UnmarshalText() */}} {{- else if .Child.IsArray -}}{{ .Zero }}{{/* initialization strategy with json.Unmarshal() */}} {{- else if and .Child.IsPrimitive (not .Child.IsCustomFormatter) -}}{{.GoType}}{{- arrayInitializer .Default }}{{/* regular go primitive type initializer: simple slice initializer */}} - {{- else }}{{ printf "%#v" .Default }}{{/* all other cases (e.g. schema) [should not occur] */}} + {{- else }}{{ printGoLiteral .Default }}{{/* all other cases (e.g. schema) [should not occur] */}} {{- end }} - {{- else }}{{ printf "%#v" .Default }}{{/* case .Schema */}} + {{- else }}{{ printGoLiteral .Default }}{{/* case .Schema */}} {{- end }} {{- end }} {{- end }} @@ -184,7 +184,7 @@ func ({{ .ReceiverName }} *{{ pascalize .Name }}) WriteResponse(rw http.Response {{ template "serverheaderbuilder" . -}} {{ end }} {{ if not .Schema }} - rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + rw.Header().Del(runtime.HeaderContentType) // Remove Content-Type on empty responses {{ end }} rw.WriteHeader({{ if eq .Code -1 }}{{ .ReceiverName }}._statusCode{{ else }}{{ .Code }}{{ end }}) {{- if .Schema }} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/server.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/server.gotmpl index ccbc520b0..db60ba325 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/server.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/server.gotmpl @@ -56,9 +56,11 @@ func init() { } {{ if not .UseGoStructFlags}} -var ({{ if .ExcludeSpec }} +var ( + {{- if .ExcludeSpec }} specFile string - {{ end }}enabledListeners []string + {{- end }} + enabledListeners []string cleanupTimeout time.Duration gracefulTimeout time.Duration maxHeaderSize flagext.ByteSize @@ -83,7 +85,7 @@ var ({{ if .ExcludeSpec }} tlsCACertificate string ) -{{ if .UseFlags}} + {{ if .UseFlags}} // StringSliceVar support for flag type sliceValue []string @@ -97,22 +99,22 @@ func (s *sliceValue) Set(val string) error { return nil } -func (s *sliceValue) Get() interface{} { return []string(*s) } +func (s *sliceValue) Get() any { return []string(*s) } func (s *sliceValue) String() string { return strings.Join([]string(*s), ",") } // end StringSliceVar support for flag -{{ end }} + {{- end }} func init() { - maxHeaderSize = flagext.ByteSize(1000000){{ if .ExcludeSpec }} - flag.StringVarP(&specFile, "spec", "", "", "the swagger specification to serve") - {{ end }} - {{ if .UseFlags }} - flag.Var(newSliceValue(defaultSchemes, &enabledListeners), "schema", "the listeners to enable, this can be repeated and defaults to the schemes in the swagger spec") - {{ end }} - {{ if .UsePFlags }} + maxHeaderSize = flagext.ByteSize(1000000) + {{- if .ExcludeSpec }} + flag.StringVar(&specFile, "spec", "", "the swagger specification to serve") + {{- end }} + {{- if .UseFlags }} + flag.Var(newSliceValue(defaultSchemes, &enabledListeners), "scheme", "the listeners to enable, this can be repeated and defaults to the schemes in the swagger spec") + {{- else if .UsePFlags }} flag.StringSliceVar(&enabledListeners, "scheme", defaultSchemes, "the listeners to enable, this can be repeated and defaults to the schemes in the swagger spec") - {{ end }} + {{- end }} flag.DurationVar(&cleanupTimeout, "cleanup-timeout", 10*time.Second, "grace period for which to wait before killing idle connections") flag.DurationVar(&gracefulTimeout, "graceful-timeout", 15*time.Second, "grace period for which to wait before shutting down the server") flag.Var(&maxHeaderSize, "max-header-size", "controls the maximum number of bytes the server will read parsing the request header's keys and values, including the request line. It does not limit the size of the request body") @@ -165,7 +167,7 @@ func intEnvOverride(orig int, def int, keys ...string) int { } return orig } -{{ end }} +{{- end }} // NewServer creates a new api {{ humanize .Name }} server but does not configure it func NewServer(api *{{ .APIPackageAlias }}.{{ pascalize .Name }}API) *Server { @@ -192,7 +194,7 @@ func NewServer(api *{{ .APIPackageAlias }}.{{ pascalize .Name }}API) *Server { s.TLSReadTimeout = tlsReadTimeout s.TLSWriteTimeout = tlsWriteTimeout {{- if .ExcludeSpec }} - s.Spec = specFile + s.Spec = specFile {{- end }} {{- end }} s.shutdown = make(chan struct{}) @@ -255,7 +257,7 @@ type Server struct { } // Logf logs message either via defined user logger or via system one if no user logger is defined. -func (s *Server) Logf(f string, args ...interface{}) { +func (s *Server) Logf(f string, args ...any) { if s.api != nil && s.api.Logger != nil { s.api.Logger(f, args...) } else { @@ -265,7 +267,7 @@ func (s *Server) Logf(f string, args ...interface{}) { // Fatalf logs message either via defined user logger or via system one if no user logger is defined. // Exits with non-zero status after printing -func (s *Server) Fatalf(f string, args ...interface{}) { +func (s *Server) Fatalf(f string, args ...any) { if s.api != nil && s.api.Logger != nil { s.api.Logger(f, args...) os.Exit(1) @@ -332,15 +334,15 @@ func (s *Server) Serve() (err error) { domainSocket.IdleTimeout = s.CleanupTimeout } - configureServer(domainSocket, "unix", string(s.SocketPath)) + configureServer(domainSocket, "unix", {{ if .UseGoStructFlags }}string({{ end }}s.SocketPath{{ if .UseGoStructFlags }}){{ end }}) servers = append(servers, domainSocket) wg.Add(1) s.Logf("Serving {{ humanize .Name }} at unix://%s", s.SocketPath) go func(l net.Listener){ defer wg.Done() - if err := domainSocket.Serve(l); err != nil && err != http.ErrServerClosed { - s.Fatalf("%v", err) + if errServe := domainSocket.Serve(l); errServe != nil && !errors.Is(errServe,http.ErrServerClosed) { + s.Fatalf("%v", errServe) } s.Logf("Stopped serving {{ humanize .Name }} at unix://%s", s.SocketPath) }(s.domainSocketL) @@ -369,8 +371,8 @@ func (s *Server) Serve() (err error) { s.Logf("Serving {{ humanize .Name }} at http://%s", s.httpServerL.Addr()) go func(l net.Listener) { defer wg.Done() - if err := httpServer.Serve(l); err != nil && err != http.ErrServerClosed { - s.Fatalf("%v", err) + if errServe := httpServer.Serve(l); errServe != nil && !errors.Is(errServe,http.ErrServerClosed) { + s.Fatalf("%v", errServe) } s.Logf("Stopped serving {{ humanize .Name }} at http://%s", l.Addr()) }(s.httpServerL) @@ -433,7 +435,7 @@ func (s *Server) Serve() (err error) { caCertPool := x509.NewCertPool() ok := caCertPool.AppendCertsFromPEM(caCert) if !ok { - return fmt.Errorf("cannot parse CA certificate") + return errors.New("cannot parse CA certificate") } httpsServer.TLSConfig.ClientCAs = caCertPool httpsServer.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert @@ -464,8 +466,8 @@ func (s *Server) Serve() (err error) { s.Logf("Serving {{ humanize .Name }} at https://%s", s.httpsServerL.Addr()) go func(l net.Listener) { defer wg.Done() - if err := httpsServer.Serve(l); err != nil && err != http.ErrServerClosed { - s.Fatalf("%v", err) + if errServe := httpsServer.Serve(l); errServe != nil && !errors.Is(errServe,http.ErrServerClosed) { + s.Fatalf("%v", errServe) } s.Logf("Stopped serving {{ humanize .Name }} at https://%s", l.Addr()) }(tls.NewListener(s.httpsServerL, httpsServer.TLSConfig)) @@ -508,7 +510,7 @@ func (s *Server) Listen() error { } if s.hasScheme(schemeUnix) { - domSockListener, err := net.Listen("unix", string(s.SocketPath)) + domSockListener, err := net.Listen("unix", {{ if .UseGoStructFlags }}string({{ end }}s.SocketPath{{ if .UseGoStructFlags }}){{ end }}) if err != nil { return err } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/urlbuilder.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/urlbuilder.gotmpl index 5d6010c0c..31ed0fd84 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/server/urlbuilder.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/server/urlbuilder.gotmpl @@ -67,7 +67,7 @@ for _, {{ .Child.ValueExpression }} := range {{ .ValueExpression }} { if len({{ varname .ID }}) > 0 { psv := {{ varname .ID }}[0] if psv != "" { - _path = strings.Replace(_path, "{{ printf "{%s}" .Name }}", psv, -1) + _path = strings.ReplaceAll(_path, "{{ printf "{%s}" .Name }}", psv) } else { return nil, errors.New("{{ camelize .ID }} is required on {{ pascalize $.Name }}URL") } @@ -147,7 +147,7 @@ func ({{ .ReceiverName }} *{{ pascalize .Name }}URL) Build() (*url.URL, error) { {{ else }} {{ varname .ID }} := {{ if .Formatter }}{{ .Formatter }}({{ .ReceiverName }}.{{ pascalize .ID }}){{ else }}{{ .ReceiverName }}.{{ pascalize .ID }}{{ if .IsCustomFormatter }}.String(){{end}}{{end}} if {{ varname .ID }} != "" { - _path = strings.Replace(_path, "{{ printf "{%s}" .Name }}", {{ varname .ID }}, -1) + _path = strings.ReplaceAll(_path, "{{ printf "{%s}" .Name }}", {{ varname .ID }}) } else { return nil, errors.New("{{ camelize .ID }} is required on {{ pascalize $.Name }}URL") } diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/simpleschema/defaultsvar.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/simpleschema/defaultsvar.gotmpl index cfb9f80e6..44aaf0e56 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/simpleschema/defaultsvar.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/simpleschema/defaultsvar.gotmpl @@ -3,12 +3,12 @@ {{- print " " }}={{ print " " }} {{- if .IsCustomFormatter }} {{- if stringContains .Zero "(\"" }} - {{- .GoType }}({{ printf "%#v" .Default }}){{/* strfmt type initializer that takes string */}} + {{- .GoType }}({{ printGoLiteral .Default }}){{/* strfmt type initializer that takes string */}} {{- else }} {{- .Zero }}{{/* strfmt type initializer that requires UnmarshalText(), e.g. Date, Datetime, Duration */}} {{- end }} {{- else }} - {{- .GoType }}({{ printf "%#v" .Default }}){{/* regular go primitive type initializer */}} + {{- .GoType }}({{ printGoLiteral .Default }}){{/* regular go primitive type initializer */}} {{- end }} {{- else if .IsArray }}{{/* do not initialize from possible defaults in nested arrays */}} {{- if .Child.IsPrimitive }} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/templates/validation/primitive.gotmpl b/vendor/github.com/go-swagger/go-swagger/generator/templates/validation/primitive.gotmpl index 8dbf79643..c90fff607 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/templates/validation/primitive.gotmpl +++ b/vendor/github.com/go-swagger/go-swagger/generator/templates/validation/primitive.gotmpl @@ -23,7 +23,7 @@ if err := validate.Pattern({{ path . }}, {{ printf "%q" .Location }}, {{ .ToStri {{ template "validationMultipleOf" . }} {{end}} {{if .Enum}} -if err := validate.EnumCase({{ path . }}, {{ printf "%q" .Location }}, {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) .IsNullable }}*{{ end }}{{.ValueExpression}}{{ if .IsCustomFormatter }}.String(){{ end }}, {{ printf "%#v" .Enum}}, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil { +if err := validate.EnumCase({{ path . }}, {{ printf "%q" .Location }}, {{ if and (not .IsArray) (not .HasDiscriminator) (not .IsInterface) .IsNullable }}*{{ end }}{{.ValueExpression}}{{ if .IsCustomFormatter }}.String(){{ end }}, {{ printGoLiteral .Enum}}, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil { return err } {{end}} diff --git a/vendor/github.com/go-swagger/go-swagger/generator/types.go b/vendor/github.com/go-swagger/go-swagger/generator/types.go index 59057ca8c..7995a957b 100644 --- a/vendor/github.com/go-swagger/go-swagger/generator/types.go +++ b/vendor/github.com/go-swagger/go-swagger/generator/types.go @@ -21,15 +21,16 @@ import ( "reflect" "strings" + "github.com/go-viper/mapstructure/v2" + "github.com/kr/pretty" + "github.com/go-openapi/loads" "github.com/go-openapi/spec" "github.com/go-openapi/swag" - "github.com/go-viper/mapstructure/v2" - "github.com/kr/pretty" ) const ( - iface = "interface{}" + iface = "any" array = "array" file = "file" number = "number" @@ -142,7 +143,7 @@ func newTypeResolver(pkg, _ string, doc *loads.Document) *typeResolver { } // knownDefGoType returns go type, package and package alias for definition -func (t typeResolver) knownDefGoType(def string, schema spec.Schema, clear func(string) string) (string, string, string) { +func (t typeResolver) knownDefGoType(def string, schema spec.Schema, clearFunc func(string) string) (string, string, string) { debugLog("known def type: %q", def) ext := schema.Extensions nm, hasGoName := ext.GetString(xGoName) @@ -153,12 +154,12 @@ func (t typeResolver) knownDefGoType(def string, schema spec.Schema, clear func( } extType, isExternalType := t.resolveExternalType(ext) if !isExternalType || extType.Embedded { - if clear == nil { + if clearFunc == nil { debugLog("known def type no clear: %q", def) return def, t.definitionPkg, "" } - debugLog("known def type clear: %q -> %q", def, clear(def)) - return clear(def), t.definitionPkg, "" + debugLog("known def type clear: %q -> %q", def, clearFunc(def)) + return clearFunc(def), t.definitionPkg, "" } // external type definition trumps regular type resolution @@ -467,6 +468,7 @@ func (t *typeResolver) resolveArray(schema *spec.Schema, isAnonymous, isRequired return } + // resolve anonymous items rt, er := t.ResolveSchema(schema.Items.Schema, true, false) if er != nil { err = er @@ -646,16 +648,16 @@ func (t *typeResolver) resolveObject(schema *spec.Schema, isAnonymous bool) (res return } - // an object without property and without AdditionalProperties schema is rendered as interface{} + // an object without property and without AdditionalProperties schema is rendered as any result.IsMap = true result.SwaggerType = object result.IsNullable = false - // an object without properties but with MinProperties or MaxProperties is rendered as map[string]interface{} + // an object without properties but with MinProperties or MaxProperties is rendered as map[string]any result.IsInterface = len(schema.Properties) == 0 && !schema.Validations().HasObjectValidations() if result.IsInterface { result.GoType = iface } else { - result.GoType = "map[string]interface{}" + result.GoType = "map[string]any" } return } @@ -697,7 +699,7 @@ func nullableNumber(schema *spec.Schema, isRequired bool) bool { isMinMax := (schema.Minimum != nil && schema.Maximum != nil && *schema.Minimum < *schema.Maximum) bcMinMax := (schema.Minimum != nil && schema.Maximum != nil && (*schema.Minimum < 0 && 0 < *schema.Maximum)) - nullable := !schema.ReadOnly && (isRequired || (hasDefault && !(isMin || isMax || isMinMax)) || bcMin || bcMax || bcMinMax) + nullable := !schema.ReadOnly && (isRequired || (hasDefault && !isMin && !isMax && !isMinMax) || bcMin || bcMax || bcMinMax) return nullable } @@ -963,7 +965,7 @@ func (t *typeResolver) ResolveSchema(schema *spec.Schema, isAnonymous, isRequire case "null": if schema.Validations().HasObjectValidations() { // no explicit object type, but inferred from object validations: - // this makes the type a map[string]interface{} instead of interface{} + // this makes the type a map[string]any instead of any result, err = t.resolveObject(schema, isAnonymous) if err != nil { result = resolvedType{} @@ -985,8 +987,8 @@ func (t *typeResolver) ResolveSchema(schema *spec.Schema, isAnonymous, isRequire return } -func warnSkipValidation(types interface{}) func(string, interface{}) { - return func(validation string, value interface{}) { +func warnSkipValidation(types any) func(string, any) { + return func(validation string, value any) { value = reflect.Indirect(reflect.ValueOf(value)).Interface() log.Printf("warning: validation %s (value: %v) not compatible with type %v. Skipped", validation, value, types) } @@ -1036,7 +1038,7 @@ func guardValidations(tpe string, schema interface { } } - // other cases: mapped as interface{}: no validations allowed but Enum + // other cases: mapped as any: no validations allowed but Enum } // guardFormatConflicts handles all conflicting properties |
