[chore] Bump go swagger (#2871)

* bump go swagger version

* bump swagger version
This commit is contained in:
tobi 2024-04-26 11:31:10 +02:00 committed by GitHub
commit fd8a724e77
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
251 changed files with 10841 additions and 11896 deletions

View file

@ -11,7 +11,7 @@ var _bindata embed.FS
// AssetNames returns the names of the assets.
func AssetNames() []string {
names := make([]string, 0)
_ = fs.WalkDir(_bindata, "templates", func(path string, d fs.DirEntry, err error) error {
_ = fs.WalkDir(_bindata, "templates", func(path string, _ fs.DirEntry, err error) error {
if err != nil {
return err
}

View file

@ -1,6 +1,7 @@
package generator
import (
"errors"
"fmt"
"os"
"path/filepath"
@ -53,7 +54,8 @@ func ReadConfig(fpath string) (*viper.Viper, error) {
v.SetConfigName(".swagger")
v.AddConfigPath(".")
if err := v.ReadInConfig(); err != nil {
if _, ok := err.(viper.UnsupportedConfigError); !ok && v.ConfigFileUsed() != "" {
var e viper.UnsupportedConfigError
if !errors.As(err, &e) && v.ConfigFileUsed() != "" {
return nil, err
}
}

View file

@ -57,6 +57,7 @@ var zeroes = map[string]string{
"strfmt.UUID3": "strfmt.UUID3(\"\")",
"strfmt.UUID4": "strfmt.UUID4(\"\")",
"strfmt.UUID5": "strfmt.UUID5(\"\")",
"strfmt.ULID": "strfmt.ULID(\"\")",
// "file": "runtime.File",
}
@ -165,6 +166,7 @@ var formatMapping = map[string]map[string]string{
"uuid3": "strfmt.UUID3",
"uuid4": "strfmt.UUID4",
"uuid5": "strfmt.UUID5",
"ulid": "strfmt.ULID",
// For file producers
"file": "runtime.File",
},

View file

@ -34,13 +34,11 @@ func (t *Repository) LoadPlugin(pluginPath string) error {
log.Printf("Attempting to load template plugin: %s", pluginPath)
p, err := plugin.Open(pluginPath)
if err != nil {
return err
}
f, err := p.Lookup("AddFuncs")
if err != nil {
return err
}

View file

@ -141,7 +141,7 @@ func (l *LanguageOpts) baseImport(tgt string) string {
// GoLangOpts for rendering items as golang code
func GoLangOpts() *LanguageOpts {
var goOtherReservedSuffixes = map[string]bool{
goOtherReservedSuffixes := map[string]bool{
// see:
// https://golang.org/src/go/build/syslist.go
// https://golang.org/doc/install/source#environment
@ -154,6 +154,7 @@ func GoLangOpts() *LanguageOpts {
"freebsd": true,
"hurd": true,
"illumos": true,
"ios": true,
"js": true,
"linux": true,
"nacl": true,
@ -172,6 +173,7 @@ func GoLangOpts() *LanguageOpts {
"armbe": true,
"arm64": true,
"arm64be": true,
"loong64": true,
"mips": true,
"mipsle": true,
"mips64": true,
@ -436,5 +438,4 @@ func checkPrefixAndFetchRelativePath(childpath string, parentpath string) (bool,
}
return false, ""
}

View file

@ -71,6 +71,10 @@ func mediaMime(orig string) string {
return strings.SplitN(orig, ";", 2)[0]
}
func mediaGoName(media string) string {
return pascalize(strings.ReplaceAll(media, "*", "Star"))
}
func mediaParameters(orig string) string {
parts := strings.SplitN(orig, ";", 2)
if len(parts) < 2 {

View file

@ -120,10 +120,9 @@ type definitionGenerator struct {
}
func (m *definitionGenerator) Generate() error {
mod, err := makeGenDefinition(m.Name, m.Target, m.Model, m.SpecDoc, m.opts)
if err != nil {
return fmt.Errorf("could not generate definitions for model %s on target %s: %v", m.Name, m.Target, err)
return fmt.Errorf("could not generate definitions for model %s on target %s: %w", m.Name, m.Target, err)
}
if m.opts.DumpData {
@ -133,7 +132,7 @@ func (m *definitionGenerator) Generate() error {
if m.opts.IncludeModel {
log.Println("including additional model")
if err := m.generateModel(mod); err != nil {
return fmt.Errorf("could not generate model: %v", err)
return fmt.Errorf("could not generate model: %w", err)
}
}
log.Println("generated model", m.Name)
@ -255,9 +254,10 @@ func makeGenDefinitionHierarchy(name, pkg, container string, schema spec.Schema,
StrictAdditionalProperties: opts.StrictAdditionalProperties,
WithXML: opts.WithXML,
StructTags: opts.StructTags,
WantsRootedErrorPath: opts.WantsRootedErrorPath,
}
if err := pg.makeGenSchema(); err != nil {
return nil, fmt.Errorf("could not generate schema for %s: %v", name, err)
return nil, fmt.Errorf("could not generate schema for %s: %w", name, err)
}
dsi, ok := di.Discriminators["#/definitions/"+name]
if ok {
@ -358,6 +358,7 @@ func makeGenDefinitionHierarchy(name, pkg, container string, schema spec.Schema,
"runtime": "github.com/go-openapi/runtime",
"swag": "github.com/go-openapi/swag",
"validate": "github.com/go-openapi/validate",
"strfmt": "github.com/go-openapi/strfmt",
}
return &GenDefinition{
@ -442,12 +443,12 @@ type schemaGenContext struct {
AdditionalProperty bool
Untyped bool
Named bool
RefHandled bool
IsVirtual bool
IsTuple bool
IncludeValidator bool
IncludeModel bool
StrictAdditionalProperties bool
WantsRootedErrorPath bool
WithXML bool
Index int
@ -473,6 +474,10 @@ type schemaGenContext struct {
// force to use container in inlined definitions (for deconflicting)
UseContainerInName bool
// indicates is the schema is part of a slice or a map
IsElem bool
// indicates is the schema is part of a struct
IsProperty bool
}
func (sg *schemaGenContext) NewSliceBranch(schema *spec.Schema) *schemaGenContext {
@ -500,6 +505,7 @@ func (sg *schemaGenContext) NewSliceBranch(schema *spec.Schema) *schemaGenContex
pg.ValueExpr = pg.ValueExpr + "[" + indexVar + "]"
pg.Schema = *schema
pg.Required = false
pg.IsElem = true
if sg.IsVirtual {
pg.TypeResolver = sg.TypeResolver.NewWithModelName(sg.TypeResolver.ModelName)
}
@ -566,6 +572,7 @@ func (sg *schemaGenContext) NewStructBranch(name string, schema spec.Schema) *sc
pg.Name = name
pg.ValueExpr = pg.ValueExpr + "." + pascalize(goName(&schema, name))
pg.Schema = schema
pg.IsProperty = true
for _, fn := range sg.Schema.Required {
if name == fn {
pg.Required = true
@ -621,6 +628,7 @@ func (sg *schemaGenContext) NewAdditionalProperty(schema spec.Schema) *schemaGen
if sg.Path != "" {
pg.Path = sg.Path + "+\".\"+" + pg.KeyVar
}
pg.IsElem = true
// propagates the special IsNullable override for maps of slices and
// maps of aliased types.
pg.GenSchema.IsMapNullOverride = sg.GenSchema.IsMapNullOverride
@ -680,7 +688,7 @@ func (sg *schemaGenContext) schemaValidations() sharedValidations {
// when readOnly or default is specified, this disables Required validation (Swagger-specific)
isRequired = false
if sg.Required {
log.Printf("warn: properties with a default value or readOnly should not be required [%s]", sg.Name)
log.Printf("warning: properties with a default value or readOnly should not be required [%s]", sg.Name)
}
}
@ -841,7 +849,7 @@ func (sg *schemaGenContext) buildProperties() error {
}
// set property name
var nm = filepath.Base(emprop.Schema.Ref.GetURL().Fragment)
nm := filepath.Base(emprop.Schema.Ref.GetURL().Fragment)
tr := sg.TypeResolver.NewWithModelName(goName(&emprop.Schema, swag.ToGoName(nm)))
ttpe, err := tr.ResolveSchema(sch, false, true)
@ -1228,7 +1236,13 @@ func (mt *mapStack) Dict() map[string]interface{} {
func (sg *schemaGenContext) buildAdditionalProperties() error {
if sg.Schema.AdditionalProperties == nil {
return nil
if sg.Schema.MinProperties == nil && sg.Schema.MaxProperties == nil {
return nil
}
// whenever there is a validation on min/max properties and no additionalProperties is defined,
// we imply additionalProperties: true (corresponds to jsonschema defaults).
sg.Schema.AdditionalProperties = &spec.SchemaOrBool{Allows: true}
}
addp := *sg.Schema.AdditionalProperties
@ -1256,7 +1270,9 @@ func (sg *schemaGenContext) buildAdditionalProperties() error {
sg.GenSchema.IsComplexObject = false
sg.GenSchema.IsMap = true
sg.GenSchema.ValueExpression += "." + swag.ToGoName(sg.Name+" additionalProperties")
if !sg.IsElem && !sg.IsProperty {
sg.GenSchema.ValueExpression += "." + swag.ToGoName(sg.Name+" additionalProperties")
}
cp := sg.NewAdditionalProperty(*addp.Schema)
cp.Name += "AdditionalProperties"
cp.Required = false
@ -1325,7 +1341,6 @@ func (sg *schemaGenContext) buildAdditionalProperties() error {
if err := comprop.makeGenSchema(); err != nil {
return err
}
sg.MergeResult(comprop, false)
sg.GenSchema.AdditionalProperties = &comprop.GenSchema
sg.GenSchema.AdditionalProperties.ValueExpression = sg.GenSchema.ValueExpression + "[" + comprop.KeyVar + "]"
@ -1598,9 +1613,8 @@ func (sg *schemaGenContext) buildItems() error {
}
func (sg *schemaGenContext) buildAdditionalItems() error {
wantsAdditionalItems :=
sg.Schema.AdditionalItems != nil &&
(sg.Schema.AdditionalItems.Allows || sg.Schema.AdditionalItems.Schema != nil)
wantsAdditionalItems := sg.Schema.AdditionalItems != nil &&
(sg.Schema.AdditionalItems.Allows || sg.Schema.AdditionalItems.Schema != nil)
sg.GenSchema.HasAdditionalItems = wantsAdditionalItems
if wantsAdditionalItems {
@ -1672,8 +1686,7 @@ func (sg *schemaGenContext) shortCircuitNamedRef() (bool, error) {
// NOTE: this assumes that all $ref point to a definition,
// i.e. the spec is canonical, as guaranteed by minimal flattening.
//
// TODO: RefHandled is actually set nowhere
if sg.RefHandled || !sg.Named || sg.Schema.Ref.String() == "" {
if !sg.Named || sg.Schema.Ref.String() == "" {
return false, nil
}
debugLogAsJSON("short circuit named ref: %q", sg.Schema.Ref.String(), sg.Schema)
@ -1684,6 +1697,8 @@ func (sg *schemaGenContext) shortCircuitNamedRef() (bool, error) {
// check if the $ref points to a simple type or polymorphic (base) type.
//
// If this is the case, just realias this simple type, without creating a struct.
//
// In templates this case is identified by .IsSuperAlias = true
asch, era := analysis.Schema(analysis.SchemaOpts{
Root: sg.TypeResolver.Doc.Spec(),
BasePath: sg.TypeResolver.Doc.SpecFilePath(),
@ -1734,10 +1749,16 @@ func (sg *schemaGenContext) shortCircuitNamedRef() (bool, error) {
}
// Aliased object: use golang struct composition.
// Covers case of a type redefinition like:
// thistype:
// $ref: #/definitions/othertype
//
// This is rendered as a struct with type field, i.e. :
// Alias struct {
// AliasedType
// }
//
// In templates, the schema is composed like AllOf.
nullableOverride := sg.GenSchema.IsNullable
tpe := resolvedType{}
@ -1750,17 +1771,26 @@ func (sg *schemaGenContext) shortCircuitNamedRef() (bool, error) {
tpe.IsAnonymous = false
tpe.IsNullable = sg.TypeResolver.isNullable(&sg.Schema)
item := sg.NewCompositionBranch(sg.Schema, 0)
if err := item.makeGenSchema(); err != nil {
branch := sg.NewCompositionBranch(sg.Schema, 0)
if err := branch.makeGenSchema(); err != nil {
return true, err
}
sg.GenSchema.resolvedType = tpe
sg.GenSchema.IsNullable = sg.GenSchema.IsNullable || nullableOverride
// prevent format from bubbling up in composed type
item.GenSchema.IsCustomFormatter = false
branch.GenSchema.IsCustomFormatter = false
sg.MergeResult(branch, true)
tpx, ers := sg.TypeResolver.ResolveSchema(&sg.Schema, false, true)
if ers != nil {
return false, ers
}
// we don't know the actual validation status yet. So assume true,
// unless we can infer that no Validate() method will be present
branch.GenSchema.HasValidations = !tpx.IsInterface && !tpx.IsStream
sg.GenSchema.AllOf = append(sg.GenSchema.AllOf, branch.GenSchema)
sg.MergeResult(item, true)
sg.GenSchema.AllOf = append(sg.GenSchema.AllOf, item.GenSchema)
return true, nil
}
@ -1967,6 +1997,9 @@ func (sg *schemaGenContext) makeGenSchema() error {
sg.GenSchema.Default = sg.Schema.Default
sg.GenSchema.StructTags = sg.StructTags
sg.GenSchema.ExtraImports = make(map[string]string)
sg.GenSchema.WantsRootedErrorPath = sg.WantsRootedErrorPath
sg.GenSchema.IsElem = sg.IsElem
sg.GenSchema.IsProperty = sg.IsProperty
var err error
returns, err := sg.shortCircuitNamedRef()
@ -1974,6 +2007,7 @@ func (sg *schemaGenContext) makeGenSchema() error {
return err
}
if returns {
// short circuited on a resolved $ref
return nil
}
debugLogAsJSON("after short circuit named ref", sg.Schema)
@ -2035,6 +2069,8 @@ func (sg *schemaGenContext) makeGenSchema() error {
log.Printf("INFO: type %s is external, with inferred spec type %s, referred to as %s", sg.GenSchema.Name, sg.GenSchema.GoType, extType)
sg.GenSchema.GoType = extType
sg.GenSchema.AliasedType = extType
// short circuit schema building for external types
return nil
}
// TODO: case for embedded types as anonymous definitions
@ -2073,6 +2109,8 @@ func (sg *schemaGenContext) makeGenSchema() error {
sg.GenSchema.IsMap = prev.IsMap
sg.GenSchema.IsAdditionalProperties = prev.IsAdditionalProperties
sg.GenSchema.IsBaseType = sg.GenSchema.HasDiscriminator
sg.GenSchema.IsElem = prev.IsElem
sg.GenSchema.IsProperty = prev.IsProperty
debugLogAsJSON("gschema nnullable:IsNullable:%t,resolver.IsNullable:%t,nullableOverride:%t",
sg.GenSchema.IsNullable, otn, nullableOverride, sg.Schema)
@ -2114,5 +2152,6 @@ func (sg *schemaGenContext) makeGenSchema() error {
(gs.IsTuple || gs.IsComplexObject || gs.IsAdditionalProperties || (gs.IsPrimitive && gs.IsAliased && gs.IsCustomFormatter && !strings.Contains(gs.Zero(), `("`)))
debugLog("finished gen schema for %q", sg.Name)
return nil
}

View file

@ -18,7 +18,9 @@ import (
"encoding/json"
"errors"
"fmt"
"log"
"path/filepath"
"regexp"
"sort"
"strings"
@ -149,7 +151,6 @@ type operationGenerator struct {
// Generate a single operation
func (o *operationGenerator) Generate() error {
defaultImports := o.GenOpts.defaultImports()
apiPackage := o.GenOpts.LanguageOpts.ManglePackagePath(o.GenOpts.APIPackage, defaultOperationsTarget)
@ -164,6 +165,7 @@ func (o *operationGenerator) Generate() error {
Imports: imports,
DefaultScheme: o.DefaultScheme,
Doc: o.Doc,
PristineDefs: o.Doc.Pristine(),
Analyzed: o.Analyzed,
BasePath: o.BasePath,
GenOpts: o.GenOpts,
@ -223,7 +225,7 @@ type codeGenOpBuilder struct {
Target string
Operation spec.Operation
Doc *loads.Document
PristineDoc *loads.Document
PristineDefs *loads.Document
Analyzed *analysis.Spec
DefaultImports map[string]string
Imports map[string]string
@ -245,12 +247,24 @@ func paramMappings(params map[string]spec.Parameter) (map[string]map[string]stri
"header": make(map[string]string, len(params)),
"body": make(map[string]string, len(params)),
}
debugLog("paramMappings: map=%v", params)
// 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]interface{}, len(params))
for id, p := range params {
if val, ok := seenIds[p.Name]; ok {
debugLog("paramMappings: params: id=%s, In=%q, Name=%q", id, p.In, p.Name)
// guard against possible validation failures and/or skipped issues
if _, found := idMapping[p.In]; !found {
log.Printf(`warning: parameter named %q has an invalid "in": %q. Skipped`, p.Name, p.In)
continue
}
if p.Name == "" {
log.Printf(`warning: unnamed parameter (%+v). Skipped`, p)
continue
}
if val, ok := seenIDs[p.Name]; ok {
previous := val.(struct{ id, in string })
idMapping[p.In][p.Name] = swag.ToGoName(id)
// rewrite the previously found one
@ -258,11 +272,11 @@ func paramMappings(params map[string]spec.Parameter) (map[string]map[string]stri
} else {
idMapping[p.In][p.Name] = swag.ToGoName(p.Name)
}
seenIds[strings.ToLower(idMapping[p.In][p.Name])] = struct{ id, in string }{id: id, in: p.In}
seenIDs[strings.ToLower(idMapping[p.In][p.Name])] = struct{ id, in string }{id: id, in: p.In}
}
// pick a deconflicted private name for timeout for this operation
timeoutName := renameTimeout(seenIds, "timeout")
timeoutName := renameTimeout(seenIDs, "timeout")
return idMapping, timeoutName
}
@ -272,12 +286,12 @@ 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 {
if seenIds == nil {
func renameTimeout(seenIDs map[string]interface{}, timeoutName string) string {
if seenIDs == nil {
return timeoutName
}
current := strings.ToLower(timeoutName)
if _, ok := seenIds[current]; !ok {
if _, ok := seenIDs[current]; !ok {
return timeoutName
}
var next string
@ -297,7 +311,7 @@ func renameTimeout(seenIds map[string]interface{}, timeoutName string) string {
default:
next = timeoutName + "1"
}
return renameTimeout(seenIds, next)
return renameTimeout(seenIDs, next)
}
func (b *codeGenOpBuilder) MakeOperation() (GenOperation, error) {
@ -325,7 +339,6 @@ func (b *codeGenOpBuilder) MakeOperation() (GenOperation, error) {
for _, p := range paramsForOperation {
cp, err := b.MakeParameter(receiver, resolver, p, idMapping)
if err != nil {
return GenOperation{}, err
}
@ -417,10 +430,7 @@ func (b *codeGenOpBuilder) MakeOperation() (GenOperation, error) {
originalExtraSchemes := getExtraSchemes(operation.Extensions)
produces := producesOrDefault(operation.Produces, swsp.Produces, b.DefaultProduces)
sort.Strings(produces)
consumes := producesOrDefault(operation.Consumes, swsp.Consumes, b.DefaultConsumes)
sort.Strings(consumes)
var successResponse *GenResponse
for _, resp := range successResponses {
@ -718,7 +728,12 @@ func (b *codeGenOpBuilder) MakeParameter(receiver string, resolver *typeResolver
b.Method, b.Path, param.Name, goName)
}
} else if len(idMapping) > 0 {
id = idMapping[param.In][param.Name]
id, ok = idMapping[param.In][param.Name]
if !ok {
// skipped parameter
return GenParameter{}, fmt.Errorf(`%s %s, %q has an invalid parameter definition`,
b.Method, b.Path, param.Name)
}
}
res := GenParameter{
@ -739,6 +754,16 @@ func (b *codeGenOpBuilder) MakeParameter(receiver string, resolver *typeResolver
Extensions: param.Extensions,
}
if goCustomTag, ok := param.Extensions["x-go-custom-tag"]; ok {
customTag, ok := goCustomTag.(string)
if !ok {
return GenParameter{}, fmt.Errorf(`%s %s, parameter %q: "x-go-custom-tag" field must be a string, not a %T`,
b.Method, b.Path, param.Name, goCustomTag)
}
res.CustomTag = customTag
}
if param.In == "body" {
// Process parameters declared in body (i.e. have a Schema)
res.Required = param.Required
@ -964,7 +989,6 @@ func (b *codeGenOpBuilder) setBodyParamValidation(p *GenParameter) {
p.HasModelBodyMap = hasModelBodyMap
p.HasSimpleBodyMap = hasSimpleBodyMap
}
}
// makeSecuritySchemes produces a sorted list of security schemes for this operation
@ -1012,10 +1036,7 @@ func (b *codeGenOpBuilder) cloneSchema(schema *spec.Schema) *spec.Schema {
// This uses a deep clone the spec document to construct a type resolver which knows about definitions when the making of this operation started,
// and only these definitions. We are not interested in the "original spec", but in the already transformed spec.
func (b *codeGenOpBuilder) saveResolveContext(resolver *typeResolver, schema *spec.Schema) (*typeResolver, *spec.Schema) {
if b.PristineDoc == nil {
b.PristineDoc = b.Doc.Pristine()
}
rslv := newTypeResolver(b.GenOpts.LanguageOpts.ManglePackageName(resolver.ModelsPackage, defaultModelsTarget), b.DefaultImports[b.ModelsPackage], b.PristineDoc)
rslv := newTypeResolver(b.GenOpts.LanguageOpts.ManglePackageName(resolver.ModelsPackage, defaultModelsTarget), b.DefaultImports[b.ModelsPackage], b.PristineDefs)
return rslv, b.cloneSchema(schema)
}
@ -1226,11 +1247,19 @@ func (b *codeGenOpBuilder) analyzeTags() (string, []string, bool) {
// conflict with "operations" package is handled separately
tag = renameOperationPackage(intersected, tag)
}
if matches := versionedPkgRex.FindStringSubmatch(tag); len(matches) > 2 {
// rename packages like "v1", "v2" ... as they hold a special meaning for go
tag = "version" + matches[2]
}
b.APIPackage = b.GenOpts.LanguageOpts.ManglePackageName(tag, b.APIPackage) // actual package name
b.APIPackageAlias = deconflictTag(intersected, b.APIPackage) // deconflicted import alias
return tag, intersected, len(filter) == 0 || len(filter) > 0 && len(intersected) > 0
}
var versionedPkgRex = regexp.MustCompile(`(?i)(v)([0-9]+)`)
func maxInt(a, b int) int {
if a > b {
return a
@ -1268,6 +1297,7 @@ func deconflictPkg(pkg string, renamer func(string) string) string {
case "tls", "http", "fmt", "strings", "log", "flags", "pflag", "json", "time":
return renamer(pkg)
}
return pkg
}

View file

@ -68,15 +68,21 @@ func DefaultSectionOpts(gen *GenOpts) {
FileName: "{{ (snakize (pascalize .Name)) }}.go",
},
}
if gen.IncludeCLi {
opts = append(opts, TemplateOpts{
sec.Models = opts
}
if len(sec.PostModels) == 0 && gen.IncludeCLi {
// For CLI, we need to postpone the generation of model-supporting source,
// in order for go imports to run properly in all cases.
opts := []TemplateOpts{
{
Name: "clidefinitionhook",
Source: "asset:cliModelcli",
Target: "{{ joinFilePath .Target (toPackagePath .CliPackage) }}",
FileName: "{{ (snakize (pascalize .Name)) }}_model.go",
})
},
}
sec.Models = opts
sec.PostModels = opts
}
if len(sec.Operations) == 0 {
@ -228,7 +234,6 @@ func DefaultSectionOpts(gen *GenOpts) {
Target: "{{ joinFilePath .Target (toPackagePath .ServerPackage) }}",
FileName: "auto_configure_{{ (snakize (pascalize .Name)) }}.go",
})
} else {
opts = append(opts, TemplateOpts{
Name: "configure",
@ -242,7 +247,6 @@ func DefaultSectionOpts(gen *GenOpts) {
}
}
gen.Sections = sec
}
// MarkdownOpts for rendering a spec as markdown
@ -255,6 +259,7 @@ func MarkdownOpts() *LanguageOpts {
// MarkdownSectionOpts for a given opts and output file.
func MarkdownSectionOpts(gen *GenOpts, output string) {
gen.Sections.Models = nil
gen.Sections.PostModels = nil
gen.Sections.OperationGroups = nil
gen.Sections.Operations = nil
gen.LanguageOpts = MarkdownOpts()
@ -284,6 +289,7 @@ type SectionOpts struct {
Operations []TemplateOpts `mapstructure:"operations"`
OperationGroups []TemplateOpts `mapstructure:"operation_groups"`
Models []TemplateOpts `mapstructure:"models"`
PostModels []TemplateOpts `mapstructure:"post_models"`
}
// GenOptsCommon the options for the generator
@ -344,6 +350,7 @@ type GenOptsCommon struct {
AllowEnumCI bool
StrictResponders bool
AcceptDefinitionsOnly bool
WantsRootedErrorPath bool
templates *Repository // a shallow clone of the global template repository
}
@ -356,7 +363,7 @@ func (g *GenOpts) CheckOpts() error {
if !filepath.IsAbs(g.Target) {
if _, err := filepath.Abs(g.Target); err != nil {
return fmt.Errorf("could not locate target %s: %v", g.Target, err)
return fmt.Errorf("could not locate target %s: %w", g.Target, err)
}
}
@ -602,11 +609,11 @@ func (g *GenOpts) render(t *TemplateOpts, data interface{}) ([]byte, error) {
}
content, err := os.ReadFile(templateFile)
if err != nil {
return nil, fmt.Errorf("error while opening %s template file: %v", templateFile, err)
return nil, fmt.Errorf("error while opening %s template file: %w", templateFile, err)
}
tt, err := template.New(t.Source).Funcs(FuncMapFunc(g.LanguageOpts)).Parse(string(content))
if err != nil {
return nil, fmt.Errorf("template parsing failed on template %s: %v", t.Name, err)
return nil, fmt.Errorf("template parsing failed on template %s: %w", t.Name, err)
}
templ = tt
}
@ -617,7 +624,7 @@ func (g *GenOpts) render(t *TemplateOpts, data interface{}) ([]byte, error) {
var tBuf bytes.Buffer
if err := templ.Execute(&tBuf, data); err != nil {
return nil, fmt.Errorf("template execution failed for template %s: %v", t.Name, err)
return nil, fmt.Errorf("template execution failed for template %s: %w", t.Name, err)
}
log.Printf("executed template %s", t.Source)
@ -631,7 +638,7 @@ func (g *GenOpts) render(t *TemplateOpts, data interface{}) ([]byte, error) {
func (g *GenOpts) write(t *TemplateOpts, data interface{}) error {
dir, fname, err := g.location(t, data)
if err != nil {
return fmt.Errorf("failed to resolve template location for template %s: %v", t.Name, err)
return fmt.Errorf("failed to resolve template location for template %s: %w", t.Name, err)
}
if t.SkipExists && fileExists(dir, fname) {
@ -643,7 +650,7 @@ func (g *GenOpts) write(t *TemplateOpts, data interface{}) error {
log.Printf("creating generated file %q in %q as %s", fname, dir, t.Name)
content, err := g.render(t, data)
if err != nil {
return fmt.Errorf("failed rendering template data for %s: %v", t.Name, err)
return fmt.Errorf("failed rendering template data for %s: %w", t.Name, err)
}
if dir != "" {
@ -652,7 +659,7 @@ func (g *GenOpts) write(t *TemplateOpts, data interface{}) error {
debugLog("creating directory %q for \"%s\"", dir, t.Name)
// Directory settings consistent with file privileges.
// Environment's umask may alter this setup
if e := os.MkdirAll(dir, 0755); e != nil {
if e := os.MkdirAll(dir, 0o755); e != nil {
return e
}
}
@ -666,18 +673,18 @@ func (g *GenOpts) write(t *TemplateOpts, data interface{}) error {
formatted, err = g.LanguageOpts.FormatContent(filepath.Join(dir, fname), content)
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, 0644) // #nosec
writeerr = os.WriteFile(filepath.Join(dir, fname), content, 0o644) // #nosec
if writeerr != nil {
return fmt.Errorf("failed to write (unformatted) file %q in %q: %v", fname, dir, writeerr)
return fmt.Errorf("failed to write (unformatted) file %q in %q: %w", fname, dir, writeerr)
}
log.Printf("unformatted generated source %q has been dumped for template debugging purposes. DO NOT build on this source!", fname)
return fmt.Errorf("source formatting on generated source %q failed: %v", t.Name, err)
return fmt.Errorf("source formatting on generated source %q failed: %w", t.Name, err)
}
}
writeerr = os.WriteFile(filepath.Join(dir, fname), formatted, 0644) // #nosec
writeerr = os.WriteFile(filepath.Join(dir, fname), formatted, 0o644) // #nosec
if writeerr != nil {
return fmt.Errorf("failed to write file %q in %q: %v", fname, dir, writeerr)
return fmt.Errorf("failed to write file %q in %q: %w", fname, dir, writeerr)
}
return err
}
@ -713,6 +720,20 @@ func (g *GenOpts) renderApplication(app *GenApp) error {
return err
}
}
if len(g.Sections.PostModels) > 0 {
log.Printf("post-rendering from %d models", len(app.Models))
for _, templateToPin := range g.Sections.PostModels {
templateConfig := templateToPin
for _, modelToPin := range app.Models {
modelData := modelToPin
if err := g.write(&templateConfig, modelData); err != nil {
return err
}
}
}
}
return nil
}
@ -1069,7 +1090,7 @@ func dumpData(data interface{}) error {
if err != nil {
return err
}
fmt.Fprintln(os.Stdout, string(bb))
fmt.Fprintln(os.Stdout, string(bb)) // TODO(fred): not testable
return nil
}

View file

@ -41,8 +41,11 @@ func (g *GenOpts) validateAndFlattenSpec() (*loads.Document, error) {
if validationErrors != nil {
str := fmt.Sprintf("The swagger spec at %q is invalid against swagger specification %s. see errors :\n",
g.Spec, specDoc.Version())
for _, desc := range validationErrors.(*swaggererrors.CompositeError).Errors {
str += fmt.Sprintf("- %s\n", desc)
var cerr *swaggererrors.CompositeError
if errors.As(validationErrors, &cerr) {
for _, desc := range cerr.Errors {
str += fmt.Sprintf("- %s\n", desc)
}
}
return nil, errors.New(str)
}
@ -84,6 +87,16 @@ func (g *GenOpts) validateAndFlattenSpec() (*loads.Document, error) {
return nil, err
}
if g.FlattenOpts.Expand {
// for a similar reason as the one mentioned above for validate,
// schema expansion alters the internal doc cache in the spec.
// This nasty bug (in spec expander) affects circular references.
// So we need to reload the spec from a clone.
// Notice that since the spec inside the document has been modified, we should
// ensure that Pristine refreshes its row root document.
specDoc = specDoc.Pristine()
}
// yields the preprocessed spec document
return specDoc, nil
}
@ -229,7 +242,7 @@ func WithAutoXOrder(specPath string) string {
}
tmpFile := filepath.Join(tmpDir, filepath.Base(specPath))
if err := os.WriteFile(tmpFile, out, 0600); err != nil {
if err := os.WriteFile(tmpFile, out, 0o600); err != nil {
panic(err)
}
return tmpFile

View file

@ -20,6 +20,7 @@ import (
type GenCommon struct {
Copyright string
TargetImportPath string
RootedErrorPath bool // wants array and map types to have a path corresponding to their type in reported errors
}
// GenDefinition contains all the properties to generate a
@ -85,6 +86,8 @@ type GenSchema struct {
HasBaseType bool
IsSubType bool
IsExported bool
IsElem bool // IsElem gives some context when the schema is part of an array or a map
IsProperty bool // IsProperty gives some context when the schema is a property of an object
DiscriminatorField string
DiscriminatorValue string
Discriminates map[string]string
@ -96,6 +99,7 @@ type GenSchema struct {
StructTags []string
ExtraImports map[string]string // non-standard imports detected when using external types
ExternalDocs *spec.ExternalDocumentation
WantsRootedErrorPath bool
}
func (g GenSchema) renderMarshalTag() string {
@ -361,6 +365,8 @@ type GenParameter struct {
CollectionFormat string
CustomTag string
Child *GenItems
Parent *GenItems
@ -514,6 +520,8 @@ type GenOperationGroup struct {
RootPackage string
GenOpts *GenOpts
PackageAlias string
ClientOptions *GenClientOptions
}
// GenOperationGroups is a sorted collection of operation groups
@ -801,3 +809,10 @@ type GenSecurityRequirements []GenSecurityRequirement
func (g GenSecurityRequirements) Len() int { return len(g) }
func (g GenSecurityRequirements) Swap(i, j int) { g[i], g[j] = g[j], g[i] }
func (g GenSecurityRequirements) Less(i, j int) bool { return g[i].Name < g[j].Name }
// GenClientOptions holds extra pieces of information
// to generate a client.
type GenClientOptions struct {
ProducesMediaTypes []string // filled with all producers if any method as more than 1
ConsumesMediaTypes []string // filled with all consumers if any method as more than 1
}

View file

@ -58,6 +58,9 @@ func GenerateMarkdown(output string, modelNames, operationIDs []string, opts *Ge
if err := opts.EnsureDefaults(); err != nil {
return err
}
if opts.Target != "" && opts.Target != "." {
output = filepath.Join(opts.Target, output)
}
MarkdownSectionOpts(opts, output)
generator, err := newAppGenerator("", modelNames, operationIDs, opts)
@ -184,7 +187,7 @@ func (a *appGenerator) Generate() error {
}
// optional OperationGroups templates generation
if err := a.GenOpts.renderOperationGroup(&opg); err != nil {
return fmt.Errorf("error while rendering operation group: %v", err)
return fmt.Errorf("error while rendering operation group: %w", err)
}
}
}
@ -217,11 +220,13 @@ func (a *appGenerator) GenerateSupport(ap *GenApp) error {
app.DefaultImports[pkgAlias] = serverPath
app.ServerPackageAlias = pkgAlias
// add client import for cli generation
clientPath := path.Join(baseImport,
a.GenOpts.LanguageOpts.ManglePackagePath(a.ClientPackage, defaultClientTarget))
clientPkgAlias := importAlias(clientPath)
app.DefaultImports[clientPkgAlias] = clientPath
if a.GenOpts.IncludeCLi { // no need to add this import when there is no CLI
// add client import for cli generation
clientPath := path.Join(baseImport,
a.GenOpts.LanguageOpts.ManglePackagePath(a.ClientPackage, defaultClientTarget))
clientPkgAlias := importAlias(clientPath)
app.DefaultImports[clientPkgAlias] = clientPath
}
return a.GenOpts.renderApplication(app)
}
@ -262,9 +267,11 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) {
imports := make(map[string]string, 50)
alias := deconflictPkg(a.GenOpts.LanguageOpts.ManglePackageName(a.OperationsPackage, defaultOperationsTarget), renameAPIPackage)
imports[alias] = path.Join(
baseImport,
a.GenOpts.LanguageOpts.ManglePackagePath(a.OperationsPackage, defaultOperationsTarget))
if !a.GenOpts.IsClient { // we don't want to inject this import for clients
imports[alias] = path.Join(
baseImport,
a.GenOpts.LanguageOpts.ManglePackagePath(a.OperationsPackage, defaultOperationsTarget))
}
implAlias := ""
if a.GenOpts.ImplementationPackage != "" {
@ -284,7 +291,7 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) {
a.GenOpts,
)
if err != nil {
return GenApp{}, fmt.Errorf("error in model %s while planning definitions: %v", mn, err)
return GenApp{}, fmt.Errorf("error in model %s while planning definitions: %w", mn, err)
}
if model != nil {
if !model.External {
@ -304,6 +311,10 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) {
log.Printf("planning operations (found: %d)", len(a.Operations))
genOps := make(GenOperations, 0, len(a.Operations))
consumesIndex := make(map[string][]string)
producesIndex := make(map[string][]string)
pristineDoc := a.SpecDoc.Pristine()
for operationName, opp := range a.Operations {
o := opp.Op
o.ID = operationName
@ -316,6 +327,7 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) {
Imports: imports,
DefaultScheme: a.DefaultScheme,
Doc: a.SpecDoc,
PristineDefs: pristineDoc,
Analyzed: a.Analyzed,
BasePath: a.SpecDoc.BasePath(),
GenOpts: a.GenOpts,
@ -355,7 +367,18 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) {
op.ReceiverName = receiver
op.Tags = tags // ordered tags for this operation, possibly filtered by CLI params
genOps = append(genOps, op)
allConsumes := pruneEmpty(op.ConsumesMediaTypes)
if bldr.DefaultConsumes != "" {
allConsumes = append(allConsumes, bldr.DefaultConsumes)
}
consumesIndex[bldr.Name] = allConsumes
allProduces := pruneEmpty(op.ProducesMediaTypes)
if bldr.DefaultProduces != "" {
allProduces = append(allProduces, bldr.DefaultProduces)
}
producesIndex[bldr.Name] = allProduces
if !a.GenOpts.SkipTagPackages && tag != "" {
importPath := filepath.ToSlash(
@ -364,8 +387,19 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) {
a.GenOpts.LanguageOpts.ManglePackagePath(a.OperationsPackage, defaultOperationsTarget),
a.GenOpts.LanguageOpts.ManglePackageName(bldr.APIPackage, defaultOperationsTarget),
))
// check for possible conflicts that requires import aliasing
pth, aliasUsed := defaultImports[bldr.APIPackageAlias]
if (a.GenOpts.IsClient && bldr.APIPackageAlias == a.GenOpts.ClientPackage) || // we don't want import to shadow the current package
(a.GenOpts.IncludeCLi && bldr.APIPackageAlias == a.GenOpts.CliPackage) ||
(aliasUsed && pth != importPath) { // was already imported with a different target
op.PackageAlias = renameOperationPackage(tags, bldr.APIPackageAlias)
bldr.APIPackageAlias = op.PackageAlias
}
defaultImports[bldr.APIPackageAlias] = importPath
}
genOps = append(genOps, op)
}
sort.Sort(genOps)
@ -378,8 +412,12 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) {
opGroups := make(GenOperationGroups, 0, len(opsGroupedByPackage))
for k, v := range opsGroupedByPackage {
log.Printf("operations for package packages %q (found: %d)", k, len(v))
log.Printf("operations for package %q (found: %d)", k, len(v))
sort.Sort(v)
consumesInGroup := make([]string, 0, 2)
producesInGroup := make([]string, 0, 2)
// trim duplicate extra schemas within the same package
vv := make(GenOperations, 0, len(v))
seenExtraSchema := make(map[string]bool)
@ -393,6 +431,9 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) {
}
op.ExtraSchemas = uniqueExtraSchemas
vv = append(vv, op)
consumesInGroup = concatUnique(consumesInGroup, consumesIndex[op.Name])
producesInGroup = concatUnique(producesInGroup, producesIndex[op.Name])
}
var pkg string
if len(vv) > 0 {
@ -414,6 +455,19 @@ func (a *appGenerator) makeCodegenApp() (GenApp, error) {
RootPackage: a.APIPackage,
GenOpts: a.GenOpts,
}
if a.GenOpts.IsClient {
// generating extra options to switch media type in client
if len(consumesInGroup) > 1 || len(producesInGroup) > 1 {
sort.Strings(producesInGroup)
sort.Strings(consumesInGroup)
options := &GenClientOptions{
ProducesMediaTypes: producesInGroup,
ConsumesMediaTypes: consumesInGroup,
}
opGroup.ClientOptions = options
}
}
opGroups = append(opGroups, opGroup)
}
sort.Sort(opGroups)

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"log"
"math"
"os"
"path"
@ -16,8 +17,6 @@ import (
"text/template/parse"
"unicode"
"log"
"github.com/Masterminds/sprig/v3"
"github.com/go-openapi/inflect"
"github.com/go-openapi/runtime"
@ -94,6 +93,7 @@ func DefaultFuncMap(lang *LanguageOpts) template.FuncMap {
"inspect": pretty.Sprint,
"cleanPath": path.Clean,
"mediaTypeName": mediaMime,
"mediaGoName": mediaGoName,
"arrayInitializer": lang.arrayInitializer,
"hasPrefix": strings.HasPrefix,
"stringContains": strings.Contains,
@ -134,9 +134,55 @@ func DefaultFuncMap(lang *LanguageOpts) template.FuncMap {
},
"docCollectionFormat": resolvedDocCollectionFormat,
"trimSpace": strings.TrimSpace,
"mdBlock": markdownBlock, // markdown block
"httpStatus": httpStatus,
"cleanupEnumVariant": cleanupEnumVariant,
"gt0": gt0,
"path": errorPath,
"cmdName": func(in interface{}) (string, error) {
// builds the name of a CLI command for a single operation
op, isOperation := in.(GenOperation)
if !isOperation {
ptr, ok := in.(*GenOperation)
if !ok {
return "", fmt.Errorf("cmdName should be called on a GenOperation, but got: %T", in)
}
op = *ptr
}
name := "Operation" + pascalize(op.Package) + pascalize(op.Name) + "Cmd"
return name, nil // TODO
},
"cmdGroupName": func(in interface{}) (string, error) {
// builds the name of a group of CLI commands
opGroup, ok := in.(GenOperationGroup)
if !ok {
return "", fmt.Errorf("cmdGroupName should be called on a GenOperationGroup, but got: %T", in)
}
name := "GroupOfOperations" + pascalize(opGroup.Name) + "Cmd"
return name, nil // TODO
},
"flagNameVar": func(in string) string {
// builds a flag name variable in CLI commands
return fmt.Sprintf("flag%sName", pascalize(in))
},
"flagValueVar": func(in string) string {
// builds a flag value variable in CLI commands
return fmt.Sprintf("flag%sValue", pascalize(in))
},
"flagDefaultVar": func(in string) string {
// builds a flag default value variable in CLI commands
return fmt.Sprintf("flag%sDefault", pascalize(in))
},
"flagModelVar": func(in string) string {
// builds a flag model variable in CLI commands
return fmt.Sprintf("flag%sModel", pascalize(in))
},
"flagDescriptionVar": func(in string) string {
// builds a flag description variable in CLI commands
return fmt.Sprintf("flag%sDescription", pascalize(in))
},
}
for k, v := range extra {
@ -327,7 +373,6 @@ func (t *Repository) ShallowClone() *Repository {
// LoadDefaults will load the embedded templates
func (t *Repository) LoadDefaults() {
for name, asset := range assets {
if err := t.addFile(name, string(asset), true); err != nil {
log.Fatal(err)
@ -337,26 +382,27 @@ func (t *Repository) LoadDefaults() {
// LoadDir will walk the specified path and add each .gotmpl file it finds to the repository
func (t *Repository) LoadDir(templatePath string) error {
err := filepath.Walk(templatePath, func(path string, info os.FileInfo, err error) error {
err := filepath.Walk(templatePath, func(path string, _ os.FileInfo, err error) error {
if strings.HasSuffix(path, ".gotmpl") {
if assetName, e := filepath.Rel(templatePath, path); e == nil {
if data, e := os.ReadFile(path); e == nil {
if ee := t.AddFile(assetName, string(data)); ee != nil {
return fmt.Errorf("could not add template: %v", ee)
return fmt.Errorf("could not add template: %w", ee)
}
}
// Non-readable files are skipped
}
}
if err != nil {
return err
}
// Non-template files are skipped
return nil
})
if err != nil {
return fmt.Errorf("could not complete template processing in directory \"%s\": %v", templatePath, err)
return fmt.Errorf("could not complete template processing in directory \"%s\": %w", templatePath, err)
}
return nil
}
@ -392,9 +438,8 @@ func (t *Repository) addFile(name, data string, allowOverride bool) error {
name = swag.ToJSONName(strings.TrimSuffix(name, ".gotmpl"))
templ, err := template.New(name).Funcs(t.funcs).Parse(data)
if err != nil {
return fmt.Errorf("failed to load template %s: %v", name, err)
return fmt.Errorf("failed to load template %s: %w", name, err)
}
// check if any protected templates are defined
@ -441,7 +486,6 @@ func (t *Repository) SetAllowOverride(value bool) {
}
func findDependencies(n parse.Node) []string {
var deps []string
depMap := make(map[string]bool)
@ -491,7 +535,6 @@ func findDependencies(n parse.Node) []string {
}
return deps
}
func (t *Repository) flattenDependencies(templ *template.Template, dependencies map[string]bool) map[string]bool {
@ -516,11 +559,9 @@ func (t *Repository) flattenDependencies(templ *template.Template, dependencies
}
return dependencies
}
func (t *Repository) addDependencies(templ *template.Template) (*template.Template, error) {
name := templ.Name()
deps := t.flattenDependencies(templ, nil)
@ -545,9 +586,8 @@ func (t *Repository) addDependencies(templ *template.Template) (*template.Templa
// Add it to the parse tree
templ, err = templ.AddParseTree(dep, tt.Tree)
if err != nil {
return templ, fmt.Errorf("dependency error: %v", err)
return templ, fmt.Errorf("dependency error: %w", err)
}
}
@ -576,7 +616,6 @@ func (t *Repository) DumpTemplates() {
fmt.Fprintf(buf, "Defined in `%s`\n", t.files[name])
if deps := findDependencies(templ.Tree.Root); len(deps) > 0 {
fmt.Fprintf(buf, "####requires \n - %v\n\n\n", strings.Join(deps, "\n - "))
}
fmt.Fprintln(buf, "\n---")
@ -853,3 +892,99 @@ func gt0(in *int64) bool {
// with a pointer
return in != nil && *in > 0
}
func errorPath(in interface{}) (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:
// {{ if .Path }}{{ .Path }}{{ else }}" "{{ end }},
// which becomes {{ path . }}
//
// When called for a GenParameter, GenResponse or GenOperation object, it just
// returns Path.
//
// Extra behavior for schemas, when the generation option RootedErroPath is enabled:
// In the case of arrays with an empty path, it adds the type name as the path "root",
// so consumers of reported errors get an idea of the originator.
var pth string
rooted := func(schema GenSchema) string {
if schema.WantsRootedErrorPath && schema.Path == "" && (schema.IsArray || schema.IsMap) {
return `"[` + schema.Name + `]"`
}
return schema.Path
}
switch schema := in.(type) {
case GenSchema:
pth = rooted(schema)
case *GenSchema:
if schema == nil {
break
}
pth = rooted(*schema)
case GenDefinition:
pth = rooted(schema.GenSchema)
case *GenDefinition:
if schema == nil {
break
}
pth = rooted(schema.GenSchema)
case GenParameter:
pth = schema.Path
// unchanged Path if called with other types
case *GenParameter:
if schema == nil {
break
}
pth = schema.Path
case GenResponse:
pth = schema.Path
case *GenResponse:
if schema == nil {
break
}
pth = schema.Path
case GenOperation:
pth = schema.Path
case *GenOperation:
if schema == nil {
break
}
pth = schema.Path
case GenItems:
pth = schema.Path
case *GenItems:
if schema == nil {
break
}
pth = schema.Path
case GenHeader:
pth = schema.Path
case *GenHeader:
if schema == nil {
break
}
pth = schema.Path
default:
return "", fmt.Errorf("errorPath should be called with GenSchema or GenDefinition, but got %T", schema)
}
if pth == "" {
return `""`, nil
}
return pth, nil
}
const mdNewLine = "</br>"
var mdNewLineReplacer = strings.NewReplacer("\r\n", mdNewLine, "\n", mdNewLine, "\r", mdNewLine)
func markdownBlock(in string) string {
in = strings.TrimSpace(in)
return mdNewLineReplacer.Replace(in)
}

View file

@ -1,42 +1,45 @@
// Code generated by go-swagger; DO NOT EDIT.
{{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }}
package {{ .GenOpts.CliPackage }}
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
{{ imports .DefaultImports }}
{{ imports .Imports }}
"log"
"os"
"path"
"path/filepath"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/go-openapi/runtime"
"github.com/go-openapi/swag"
httptransport "github.com/go-openapi/runtime/client"
homedir "github.com/mitchellh/go-homedir"
httptransport "github.com/go-openapi/runtime/client"
"github.com/spf13/cobra"
"github.com/spf13/viper"
{{ imports .DefaultImports }}
{{ imports .Imports }}
)
// debug flag indicating that cli should output debug logs
var debug bool
// config file location
var configFile string
// dry run flag
var dryRun bool
var (
// debug flag indicating that cli should output debug logs
debug bool
// name of the executable
var exeName string = filepath.Base(os.Args[0])
// config file location
configFile string
// dry run flag
dryRun bool
// name of the executable
exeName = filepath.Base(os.Args[0])
)
// logDebugf writes debug log to stdout
func logDebugf(format string, v ...interface{}) {
if !debug{
return
}
log.Printf(format, v...)
if !debug{
return
}
log.Printf(format, v...)
}
{{/*TODO: make this a swagger cli option*/}}
@ -44,199 +47,240 @@ func logDebugf(format string, v ...interface{}) {
var maxDepth int = 5
// makeClient constructs a client object
func makeClient(cmd *cobra.Command, args []string) (*client.{{ pascalize .Name }}, error) {
hostname := viper.GetString("hostname")
viper.SetDefault("base_path", client.DefaultBasePath)
basePath := viper.GetString("base_path")
scheme := viper.GetString("scheme")
func makeClient(cmd *cobra.Command, _ []string) (*client.{{ pascalize .Name }}, error) {
hostname := viper.GetString("hostname")
viper.SetDefault("base_path", client.DefaultBasePath)
basePath := viper.GetString("base_path")
scheme := viper.GetString("scheme")
r := httptransport.New(hostname, basePath, []string{scheme})
r.SetDebug(debug)
r := httptransport.New(hostname, basePath, []string{scheme})
r.SetDebug(debug)
{{- /* user might define custom mediatype xxx/json and there is no registered ones to handle. */}}
// set custom producer and consumer to use the default ones
{{ range .Consumes }}
{{ range .AllSerializers }}
{{- if stringContains .MediaType "json" }}
r.Consumers["{{ .MediaType }}"] = runtime.JSONConsumer()
{{- else }}
// warning: consumes {{ .MediaType }} is not supported by go-swagger cli yet
{{- end }}
{{- end }}
{{ end }}
{{ range .Produces }}
{{- range .AllSerializers }}
{{- if stringContains .MediaType "json" }}
r.Producers["{{ .MediaType }}"] = runtime.JSONProducer()
{{- else }}
// warning: produces {{ .MediaType }} is not supported by go-swagger cli yet
{{- end }}
{{- end }}
{{ end }}
{{- /* user might define custom mediatype xxx/json and there is no registered ones to handle. */}}
// set custom producer and consumer to use the default ones
{{ range .Consumes }}
{{ range .AllSerializers }}
{{- if stringContains .MediaType "json" }}
r.Consumers["{{ .MediaType }}"] = runtime.JSONConsumer()
{{- else }}
// warning: consumes {{ .MediaType }} is not supported by go-swagger cli yet
{{- end }}
{{- end }}
{{ end }}
{{ range .Produces }}
{{- range .AllSerializers }}
{{- if stringContains .MediaType "json" }}
r.Producers["{{ .MediaType }}"] = runtime.JSONProducer()
{{- else }}
// warning: produces {{ .MediaType }} is not supported by go-swagger cli yet
{{- end }}
{{- end }}
{{- end }}
{{- if .SecurityDefinitions }}
auth, err := makeAuthInfoWriter(cmd)
if err != nil {
return nil, err
}
r.DefaultAuthentication = auth
{{ end }}
appCli := client.New(r, strfmt.Default)
logDebugf("Server url: %v://%v", scheme, hostname)
return appCli, nil
{{- if .SecurityDefinitions }}
auth, err := makeAuthInfoWriter(cmd)
if err != nil {
return nil, err
}
r.DefaultAuthentication = auth
{{- end }}
appCli := client.New(r, strfmt.Default)
logDebugf("Server url: %v://%v", scheme, hostname)
return appCli, nil
}
// MakeRootCmd returns the root cmd
func MakeRootCmd() (*cobra.Command, error) {
cobra.OnInitialize(initViperConfigs)
// Use executable name as the command name
rootCmd := &cobra.Command{
Use: exeName,
}
{{/*note: viper binded flag value must be retrieved from viper rather than cmd*/}}
// register basic flags
rootCmd.PersistentFlags().String("hostname", client.DefaultHost, "hostname of the service")
viper.BindPFlag("hostname", rootCmd.PersistentFlags().Lookup("hostname"))
rootCmd.PersistentFlags().String("scheme", client.DefaultSchemes[0], fmt.Sprintf("Choose from: %v", client.DefaultSchemes))
viper.BindPFlag("scheme", rootCmd.PersistentFlags().Lookup("scheme"))
rootCmd.PersistentFlags().String("base-path", client.DefaultBasePath, fmt.Sprintf("For example: %v", client.DefaultBasePath))
viper.BindPFlag("base_path", rootCmd.PersistentFlags().Lookup("base-path"))
cobra.OnInitialize(initViperConfigs)
// configure debug flag
rootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "output debug logs")
// configure config location
rootCmd.PersistentFlags().StringVar(&configFile, "config", "", "config file path")
// configure dry run flag
rootCmd.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "do not send the request to server")
// Use executable name as the command name
rootCmd := &cobra.Command{
Use: exeName,
}
{{/*note: viper binded flag value must be retrieved from viper rather than cmd*/}}
// register basic flags
rootCmd.PersistentFlags().String("hostname", client.DefaultHost, "hostname of the service")
if err := viper.BindPFlag("hostname", rootCmd.PersistentFlags().Lookup("hostname")) ; err != nil {
return nil, err
}
rootCmd.PersistentFlags().String("scheme", client.DefaultSchemes[0], fmt.Sprintf("Choose from: %v", client.DefaultSchemes))
if err := viper.BindPFlag("scheme", rootCmd.PersistentFlags().Lookup("scheme")) ; err != nil {
return nil, err
}
rootCmd.PersistentFlags().String("base-path", client.DefaultBasePath, fmt.Sprintf("For example: %v", client.DefaultBasePath))
if err := viper.BindPFlag("base_path", rootCmd.PersistentFlags().Lookup("base-path")) ; err != nil {
return nil, err
}
// register security flags
{{- if .SecurityDefinitions }}
if err := registerAuthInoWriterFlags(rootCmd); err != nil{
return nil, err
}
{{- end }}
// add all operation groups
{{- range .OperationGroups -}}
{{- $operationGroupCmdVarName := printf "operationGroup%vCmd" (pascalize .Name) }}
{{ $operationGroupCmdVarName }}, err := makeOperationGroup{{ pascalize .Name }}Cmd()
if err != nil {
return nil, err
}
rootCmd.AddCommand({{ $operationGroupCmdVarName }})
{{ end }}
// configure debug flag
rootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "output debug logs")
// configure config location
rootCmd.PersistentFlags().StringVar(&configFile, "config", "", "config file path")
// configure dry run flag
rootCmd.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "do not send the request to server")
// add cobra completion
rootCmd.AddCommand(makeGenCompletionCmd())
// register security flags
{{- if .SecurityDefinitions }}
if err := registerAuthInoWriterFlags(rootCmd); err != nil{
return nil, err
}
{{- end }}
return rootCmd, nil
// add all operation groups
{{- range $index,$element := .OperationGroups }}
c{{ $index }}, err := make{{ cmdGroupName $element }}()
if err != nil {
return nil, err
}
rootCmd.AddCommand(c{{ $index}})
{{- end }}
// add cobra completion
rootCmd.AddCommand(makeGenCompletionCmd())
return rootCmd, nil
}
// initViperConfigs initialize viper config using config file in '$HOME/.config/<cli name>/config.<json|yaml...>'
// currently hostname, scheme and auth tokens can be specified in this config file.
func initViperConfigs() {
if configFile != "" {
// use user specified config file location
viper.SetConfigFile(configFile)
}else{
// look for default config
// Find home directory.
home, err := homedir.Dir()
cobra.CheckErr(err)
if configFile != "" {
// use user specified config file location
viper.SetConfigFile(configFile)
} else{
var (
configDir string
err error
)
// Search config in home directory with name ".cobra" (without extension).
viper.AddConfigPath(path.Join(home, ".config", exeName))
viper.SetConfigName("config")
}
// look for default config (OS-specific, e.g. ".config" on linux)
configDir, err = os.UserConfigDir()
if err != nil {
// fallback and try finding the home directory.
home, err := os.UserHomeDir()
cobra.CheckErr(err)
configDir = path.Join(home, ".config")
}
if err := viper.ReadInConfig(); err != nil {
logDebugf("Error: loading config file: %v", err)
return
}
logDebugf("Using config file: %v", viper.ConfigFileUsed())
// Search config in the config directory with name of the CLI binary (without extension).
configDir = path.Join(configDir, exeName)
viper.AddConfigPath(configDir)
viper.SetConfigName("config")
}
if err := viper.ReadInConfig(); err != nil {
logDebugf("Error: loading config file: %v", err)
return
}
logDebugf("Using config file: %v", viper.ConfigFileUsed())
}
{{- if .SecurityDefinitions }}
{{- /*youyuan: rework this since spec may define multiple auth schemes.
cli needs to detect which one user passed rather than add all of them.*/}}
{{- /*youyuan: rework this since spec may define multiple auth schemes.
cli needs to detect which one user passed rather than add all of them.*/}}
// registerAuthInoWriterFlags registers all flags needed to perform authentication
func registerAuthInoWriterFlags(cmd *cobra.Command) error {
{{- range .SecurityDefinitions }}
/*{{.Name}} {{.Description}}*/
{{- if .IsBasicAuth }}
cmd.PersistentFlags().String("username", "", "username for basic auth")
viper.BindPFlag("username", cmd.PersistentFlags().Lookup("username"))
cmd.PersistentFlags().String("password", "", "password for basic auth")
viper.BindPFlag("password", cmd.PersistentFlags().Lookup("password"))
{{- end }}
{{- if .IsAPIKeyAuth }}
cmd.PersistentFlags().String("{{.Name}}", "", `{{.Description}}`)
viper.BindPFlag("{{.Name}}", cmd.PersistentFlags().Lookup("{{.Name}}"))
{{- end }}
{{- if .IsOAuth2 }}
// oauth2: let user provide the token in a flag, rather than implement the logic to fetch the token.
cmd.PersistentFlags().String("oauth2-token", "", `{{.Description}}`)
viper.BindPFlag("oauth2-token", cmd.PersistentFlags().Lookup("oauth2-token"))
{{- end }}
{{- end }}
return nil
// {{.Name}}
{{- if .Description }}
{{- comment .Description }}
{{- end }}
{{- if .IsBasicAuth }}
cmd.PersistentFlags().String("username", "", "username for basic auth")
if err := viper.BindPFlag("username", cmd.PersistentFlags().Lookup("username")) ; err != nil {
return err
}
cmd.PersistentFlags().String("password", "", "password for basic auth")
if err := viper.BindPFlag("password", cmd.PersistentFlags().Lookup("password")) ; err != nil {
return err
}
{{- end }}
{{- if .IsAPIKeyAuth }}
cmd.PersistentFlags().String("{{.Name}}", "", `{{.Description}}`)
if err := viper.BindPFlag("{{.Name}}", cmd.PersistentFlags().Lookup("{{.Name}}")) ; err != nil {
return err
}
{{- end }}
{{- if .IsOAuth2 }}
// oauth2: let user provide the token in a flag, rather than implement the logic to fetch the token.
cmd.PersistentFlags().String("oauth2-token", "", `{{.Description}}`)
if err := viper.BindPFlag("oauth2-token", cmd.PersistentFlags().Lookup("oauth2-token")) ; err != nil {
return err
}
{{- end }}
{{ end }}
return nil
}
// makeAuthInfoWriter retrieves cmd flags and construct an auth info writer
func makeAuthInfoWriter(cmd *cobra.Command) (runtime.ClientAuthInfoWriter, error) {
auths := []runtime.ClientAuthInfoWriter{}
auths := []runtime.ClientAuthInfoWriter{}
{{- range .SecurityDefinitions }}
/*{{.Name}} {{.Description}}*/
{{- if .IsBasicAuth }}
if viper.IsSet("username") {
usr := viper.GetString("username")
if !viper.IsSet("password"){
return nil, fmt.Errorf("Basic Auth password for user [%v] is not provided.", usr)
}
pwd := viper.GetString("password")
auths = append(auths, httptransport.BasicAuth(usr,pwd))
// {{.Name}}
{{- if .Description }}
{{- comment .Description }}
{{- end }}
{{- if .IsBasicAuth }}
if viper.IsSet("username") {
usr := viper.GetString("username")
if !viper.IsSet("password"){
return nil, fmt.Errorf("Basic Auth password for user [%v] is not provided.", usr)
}
{{- end }}
{{- if .IsAPIKeyAuth }}
if viper.IsSet("{{.Name}}") {
{{ pascalize .Name }}Key := viper.GetString("{{.Name}}")
auths = append(auths, httptransport.APIKeyAuth("{{.Name}}", "{{.In}}", {{ pascalize .Name }}Key))
}
{{- end }}
{{- if .IsOAuth2 }}
if viper.IsSet("oauth2-token") {
// oauth2 workflow for generated CLI is not ideal.
// If you have suggestions on how to support it, raise an issue here: https://github.com/go-swagger/go-swagger/issues
// This will be added to header: "Authorization: Bearer {oauth2-token value}"
token := viper.GetString("oauth2-token")
auths = append(auths, httptransport.BearerToken(token))
}
{{- end }}
pwd := viper.GetString("password")
auths = append(auths, httptransport.BasicAuth(usr,pwd))
}
{{- end }}
{{- if .IsAPIKeyAuth }}
if viper.IsSet("{{.Name}}") {
{{ pascalize .Name }}Key := viper.GetString("{{.Name}}")
auths = append(auths, httptransport.APIKeyAuth("{{.Name}}", "{{.In}}", {{ pascalize .Name }}Key))
}
{{- end }}
{{- if .IsOAuth2 }}
if viper.IsSet("oauth2-token") {
// oauth2 workflow for generated CLI is not ideal.
// If you have suggestions on how to support it, raise an issue here: https://github.com/go-swagger/go-swagger/issues
// This will be added to header: "Authorization: Bearer {oauth2-token value}"
token := viper.GetString("oauth2-token")
auths = append(auths, httptransport.BearerToken(token))
}
{{- end }}
{{- end }}
if len(auths) == 0 {
logDebugf("Warning: No auth params detected.")
return nil, nil
}
// compose all auths together
return httptransport.Compose(auths...), nil
if len(auths) == 0 {
logDebugf("Warning: No auth params detected.")
return nil, nil
}
// compose all auths together
return httptransport.Compose(auths...), nil
}
{{- end }}
{{ range .OperationGroups -}}
func makeOperationGroup{{ pascalize .Name }}Cmd() (*cobra.Command, error) {
{{- $operationGroupCmdVarName := printf "operationGroup%vCmd" (pascalize .Name) }}
{{ $operationGroupCmdVarName }} := &cobra.Command{
Use: "{{ .Name }}",
Long: `{{ .Description }}`,
}
{{ range .Operations }}
{{- $operationCmdVarName := printf "operation%vCmd" (pascalize .Name) }}
{{ $operationCmdVarName }}, err := makeOperation{{pascalize .Package}}{{ pascalize .Name }}Cmd()
if err != nil {
return nil, err
}
{{ $operationGroupCmdVarName }}.AddCommand({{ $operationCmdVarName }})
{{ end }}
return {{ $operationGroupCmdVarName }}, nil
{{- range .OperationGroups -}}
// make{{ cmdGroupName . }} returns a parent command to handle all operations with tag {{ printf "%q" .Name }}
func make{{ cmdGroupName . }}() (*cobra.Command, error) {
parent := &cobra.Command{
Use: "{{ .Name }}",
Long: `{{ .Description }}`,
}
{{- range $index,$element := .Operations }}
sub{{ $index }}, err := make{{ cmdName $element }}()
if err != nil {
return nil, err
}
parent.AddCommand(sub{{ $index }})
{{- end }}
return parent, nil
}
{{ end }} {{/*operation group*/}}
{{- end }} {{/*operation group*/}}

View file

@ -1,28 +1,29 @@
// Code generated by go-swagger; DO NOT EDIT.
{{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }}
package main
import (
"encoding/json"
{{ imports .DefaultImports }}
{{ imports .Imports }}
"fmt"
"os"
{{ imports .DefaultImports }}
{{ imports .Imports }}
)
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
func main() {
rootCmd,err := cli.MakeRootCmd()
rootCmd, err := cli.MakeRootCmd()
if err != nil {
fmt.Println("Cmd construction error: ", err)
fmt.Println("cmd construction error: ", err)
os.Exit(1)
}
if err := rootCmd.Execute(); err != nil {
if err = rootCmd.Execute(); err != nil {
fmt.Println("cmd execute error: ", err)
os.Exit(1)
}
}
}

View file

@ -11,9 +11,12 @@ package cli
import (
{{ imports .DefaultImports }}
{{ imports .Imports }}
"github.com/spf13/cobra"
"encoding/json"
"fmt"
"github.com/spf13/cobra"
{{ imports .DefaultImports }}
{{ imports .Imports }}
)
// Schema cli for {{.GoType}}
@ -22,4 +25,4 @@ import (
{{ range .ExtraSchemas }}
// Extra schema cli for {{.GoType}}
{{ template "modelschemacli" .}}
{{ end }}
{{ end }}

View file

@ -1,26 +1,26 @@
// Code generated by go-swagger; DO NOT EDIT.
{{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }}
{{- /*TODO: do not hardcode cli pkg*/}}
package cli
package cli {{/* TODO: do not hardcode cli pkg */}}
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
{{ imports .DefaultImports }}
{{ imports .Imports }}
"fmt"
"github.com/spf13/cobra"
"github.com/go-openapi/runtime"
"github.com/go-openapi/swag"
httptransport "github.com/go-openapi/runtime/client"
{{ imports .DefaultImports }}
{{ imports .Imports }}
"github.com/spf13/cobra"
"github.com/go-openapi/runtime"
"github.com/go-openapi/swag"
httptransport "github.com/go-openapi/runtime/client"
)
// makeOperation{{pascalize .Package}}{{ pascalize .Name }}Cmd returns a cmd to handle operation {{ camelize .Name }}
func makeOperation{{pascalize .Package}}{{ pascalize .Name }}Cmd() (*cobra.Command, error) {
// make{{ cmdName . }} returns a command to handle operation {{ camelize .Name }}
func make{{ cmdName . }}() (*cobra.Command, error) {
cmd := &cobra.Command{
Use: "{{ .Name }}",
Short: `{{ escapeBackticks .Description}}`,
@ -46,12 +46,11 @@ func runOperation{{pascalize $operationGroup }}{{ pascalize $operation }}(cmd *c
// retrieve flag values from cmd and fill params
params := {{ .PackageAlias }}.New{{ pascalize .Name}}Params()
{{- range .Params }}
if err, _ := retrieveOperation{{pascalize $operationGroup }}{{ pascalize $operation }}{{ pascalize .Name }}Flag(params, "", cmd); err != nil{
if err, _ = retrieveOperation{{pascalize $operationGroup }}{{ pascalize $operation }}{{ pascalize .Name }}Flag(params, "", cmd); err != nil{
return err
}
{{- end }} {{/*Params*/}}
if dryRun {
{{/* Note: dry run is not very useful for now, but useful when validation is added in future*/}}
if dryRun { {{/* Note: dry run is not very useful for now, but useful when validation is added in future*/}}
logDebugf("dry-run flag specified. Skip sending request.")
return nil
}
@ -61,10 +60,11 @@ func runOperation{{pascalize $operationGroup }}{{ pascalize $operation }}(cmd *c
if err != nil {
return err
}
if !debug{
{{/* In debug mode content should have been printed in transport layer, so do not print again*/}}
if !debug{ {{/* In debug mode content should have been printed in transport layer, so do not print again*/}}
fmt.Println(msgStr)
}
return nil
}
@ -77,9 +77,9 @@ func registerOperation{{pascalize $operationGroup }}{{ pascalize $operation }}Pa
{{- end }}
return nil
}
{{/*register functions for each fields in this operation*/}}
{{- range .Params }}
func registerOperation{{pascalize $operationGroup }}{{ pascalize $operation }}{{pascalize .Name }}ParamFlags(cmdPrefix string, cmd *cobra.Command) error{
{{- if .IsPrimitive }}
{{ template "primitiveregistrator" . }}
@ -96,12 +96,12 @@ func registerOperation{{pascalize $operationGroup }}{{ pascalize $operation }}{{
}
{{- end }}
{{/*functions to retreive each field of params*/}}
{{/*functions to retrieve each field of params*/}}
{{- range .Params }}
func retrieveOperation{{pascalize $operationGroup }}{{ pascalize $operation }}{{ pascalize .Name }}Flag(m *{{ $operationPkgAlias }}.{{ pascalize $operation }}Params, cmdPrefix string, cmd *cobra.Command) (error,bool){
retAdded := false
{{- $flagStr := .Name }}
{{- $flagValueVar := printf "%vValue" (camelize .Name) }}
{{- /*only set the param if user set the flag*/}}
if cmd.Flags().Changed("{{ $flagStr }}") {
{{- if .IsPrimitive }}
@ -113,16 +113,16 @@ func retrieveOperation{{pascalize $operationGroup }}{{ pascalize $operation }}{{
{{- else if and .IsBodyParam .Schema .IsComplexObject (not .IsStream) }}
{{- /*schema payload can be passed in cmd as a string and here is unmarshalled to model struct and attached in params*/}}
// Read {{ $flagStr }} string from cmd and unmarshal
{{ $flagValueVar }}Str, err := cmd.Flags().GetString("{{ $flagStr }}")
{{ flagValueVar .Name }}Str, err := cmd.Flags().GetString("{{ $flagStr }}")
if err != nil {
return err, false
}
{{/*Note anonymous body schema is not pointer*/}}
{{ $flagValueVar }} := {{if containsPkgStr .GoType}}{{ .GoType }}{{else}}{{ .Pkg }}.{{.GoType}}{{ end }}{}
if err := json.Unmarshal([]byte({{ $flagValueVar }}Str), &{{ $flagValueVar }}); err!= nil{
{{ 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
}
m.{{ .ID }} = {{- if .IsNullable }}&{{- end }}{{ $flagValueVar }}
m.{{ .ID }} = {{- if .IsNullable }}&{{- end }}{{ flagValueVar .Name }}
{{- else }}
// warning: {{.GoType}} is not supported by go-swagger cli yet
{{- end }} {{/*end go type case*/}}
@ -131,32 +131,32 @@ func retrieveOperation{{pascalize $operationGroup }}{{ pascalize $operation }}{{
{{- /* Add flags to capture fields in Body. If previously Body struct was constructed in unmarshalling body string,
then reuse the struct, otherwise construct an empty value struct to fill. Here body field flags overwrites
unmarshalled body string values. */}}
{{- $flagModelVar := printf "%vModel" (camelize $flagValueVar) }}
{{ $flagModelVar }} := m.{{ .ID }}
if swag.IsZero({{ $flagModelVar }}){
{{ $flagModelVar }} = {{- if .IsNullable }}&{{- end }}{{if containsPkgStr .GoType}}{{ .GoType }}{{else}}{{ .Pkg }}.{{.GoType}}{{ end }}{}
{{ flagModelVar .Name }} := m.{{ .ID }}
if swag.IsZero({{ flagModelVar .Name }}){
{{ flagModelVar .Name }} = {{- if .IsNullable }}&{{- end }}{{if containsPkgStr .GoType}}{{ .GoType }}{{else}}{{ .Pkg }}.{{.GoType}}{{ end }}{}
}
{{- /*Only attach the body struct in params if user passed some flag filling some body fields.*/}}
{{- /* add "&" to $flagModelVar when it is not nullable because the retrieve method always expects a pointer */}}
err, added := retrieveModel{{ pascalize (dropPackage .GoType) }}Flags(0, {{if not .IsNullable}}&{{end}}{{ $flagModelVar }}, "{{ camelize (dropPackage .GoType) }}", cmd)
{{- /* add "&" to flagModelVar .Name when it is not nullable because the retrieve method always expects a pointer */}}
err, added := retrieveModel{{ pascalize (dropPackage .GoType) }}Flags(0, {{if not .IsNullable}}&{{end}}{{ flagModelVar .Name }}, "{{ camelize (dropPackage .GoType) }}", cmd)
if err != nil{
return err, false
}
if added {
m.{{.ID}} = {{ $flagModelVar }}
m.{{.ID}} = {{ flagModelVar .Name }}
}
if dryRun && debug {
{{/* dry run we don't get trasnport debug strings, so print it here*/}}
{{- $bodyDebugVar := printf "%vDebugBytes" (camelize $flagValueVar) }}
if dryRun && debug { {{/* dry run we don't get trasnport debug strings, so print it here*/}}
{{- $bodyDebugVar := printf "%vDebugBytes" (flagValueVar .Name) }}
{{ $bodyDebugVar }}, err := json.Marshal(m.{{.ID}})
if err != nil{
return err, false
}
logDebugf("{{.ID }} dry-run payload: %v", string({{ $bodyDebugVar }}))
}
retAdded = retAdded || added
{{/*body debug string will be printed in transport layer*/}}
retAdded = retAdded || added {{/*body debug string will be printed in transport layer*/}}
{{- end }}
return nil, retAdded
}
{{- end }} {{/*Params*/}}

View file

@ -8,34 +8,32 @@
{{- if .Enum }}
{{- $fullDescription = printf "Enum: %v. %v" (json .Enum) $fullDescription}}
{{- end }}
{{ camelize .Name }}Description := `{{ $fullDescription }}`
{{ flagDescriptionVar .Name }} := `{{ $fullDescription }}`
{{ end }}
{{ define "flagnamevar" }}
{{- $flagNameVar := printf "%vFlagName" (camelize .Name) }}
var {{ $flagNameVar }} string
var {{ flagNameVar .Name }} string
if cmdPrefix == "" {
{{ $flagNameVar }} = "{{ .Name }}"
{{ flagNameVar .Name }} = "{{ .Name }}"
}else{
{{ $flagNameVar }} = fmt.Sprintf("%v.{{ .Name }}", cmdPrefix)
{{ flagNameVar .Name }} = fmt.Sprintf("%v.{{ .Name }}", cmdPrefix)
}
{{ end }}
{{ define "flagdefaultvar" }}
{{ $defaultVar := printf "%vFlagDefault" (camelize .Name) }}
var {{ $defaultVar}} {{ .GoType }} {{ if .Default }}= {{ printf "%#v" .Default }}{{ end }}
var {{ flagDefaultVar .Name }} {{ .GoType }} {{ if .Default }}= {{ printf "%#v" .Default }}{{ end }}
{{ end }}
{{/* Not used. CLI does not mark flag as required, and required will be checked by validation in future */}}
{{/* {{ define "requiredregistrator" }}
if err := cmd.MarkPersistentFlagRequired({{ camelize .Name }}FlagName); err != nil{
if err := cmd.MarkPersistentFlagRequired({{ flagNameVar .Name }}); err != nil{
return err
}
{{ end }} */}}
{{ define "enumcompletion" }} {{/*only used for primitive types. completion type is always string.*/}}
{{ if .Enum }}
if err := cmd.RegisterFlagCompletionFunc({{ camelize .Name }}FlagName,
if err := cmd.RegisterFlagCompletionFunc({{ flagNameVar .Name }},
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
var res []string
if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
@ -54,12 +52,12 @@ if err := cmd.RegisterFlagCompletionFunc({{ camelize .Name }}FlagName,
{{ template "flagdescriptionvar" . }}
{{ template "flagnamevar" . }}
{{ template "flagdefaultvar" . }}
_ = cmd.PersistentFlags().{{ pascalize .GoType }}({{ camelize .Name }}FlagName, {{ camelize .Name }}FlagDefault, {{ (camelize .Name) }}Description)
_ = cmd.PersistentFlags().{{ pascalize .GoType }}({{ flagNameVar .Name }}, {{ flagDefaultVar .Name }}, {{ flagDescriptionVar .Name }})
{{ template "enumcompletion" . }}
{{- else if or (eq .GoType "strfmt.DateTime") (eq .GoType "strfmt.UUID") (eq .GoType "strfmt.ObjectId") }} {{/* read as string */}}
{{- else if or (eq .GoType "strfmt.DateTime") (eq .GoType "strfmt.UUID") (eq .GoType "strfmt.ObjectId") (eq .GoType "strfmt.ULID") }} {{/* read as string */}}
{{ template "flagdescriptionvar" . }}
{{ template "flagnamevar" . }}
_ = cmd.PersistentFlags().String({{ camelize .Name }}FlagName, "", {{ (camelize .Name) }}Description)
_ = cmd.PersistentFlags().String({{ flagNameVar .Name }}, "", {{ flagDescriptionVar .Name }})
{{ template "enumcompletion" . }}
{{- else }}
// warning: primitive {{.Name}} {{.GoType }} is not supported by go-swagger cli yet
@ -71,12 +69,12 @@ if err := cmd.RegisterFlagCompletionFunc({{ camelize .Name }}FlagName,
{{ template "flagdescriptionvar" . }}
{{ template "flagnamevar" . }}
{{ template "flagdefaultvar" . }}
_ = cmd.PersistentFlags().{{ pascalize .GoType }}Slice({{ camelize .Name }}FlagName, {{ camelize .Name }}FlagDefault, {{ (camelize .Name) }}Description)
_ = cmd.PersistentFlags().{{ pascalize .GoType }}Slice({{ flagNameVar .Name }}, {{ flagDefaultVar .Name }}, {{ flagDescriptionVar .Name }})
{{ template "enumcompletion" . }}
{{- else if or (eq .GoType "[]strfmt.DateTime") (eq .GoType "[]strfmt.UUID") (eq .GoType "[]strfmt.ObjectId") }} {{/* read as string */}}
{{- else if or (eq .GoType "[]strfmt.DateTime") (eq .GoType "[]strfmt.UUID") (eq .GoType "[]strfmt.ObjectId") (eq .GoType "[]strfmt.ULID") }} {{/* read as string */}}
{{ template "flagdescriptionvar" . }}
{{ template "flagnamevar" . }}
_ = cmd.PersistentFlags().StringSlice({{ camelize .Name }}FlagName, []string{}, {{ (camelize .Name) }}Description)
_ = cmd.PersistentFlags().StringSlice({{ flagNameVar .Name }}, []string{}, {{ flagDescriptionVar .Name }})
{{- else }}
// warning: array {{.Name}} {{.GoType }} is not supported by go-swagger cli yet
{{- end }}
@ -86,7 +84,7 @@ if err := cmd.RegisterFlagCompletionFunc({{ camelize .Name }}FlagName,
{{/* each body parameter gets a string flag to input json raw string */}}
{{ define "modelparamstringregistrator" }}
{{ template "flagnamevar" . }}
_ = cmd.PersistentFlags().String({{ camelize .Name }}FlagName, "", "Optional json string for [{{ .Name }}]. {{ .Description }}")
_ = cmd.PersistentFlags().String({{ flagNameVar .Name }}, "", `Optional json string for [{{ .Name }}]. {{ escapeBackticks .Description }}`)
{{ end }}
{{ define "modelparamregistrator" }} {{/* register a param that has a schema */}}

View file

@ -1,59 +1,55 @@
{{/*util functions to retrieve flags*/}}
{{ define "primitiveretriever" }}
{{- $flagValueVar := printf "%vFlagValue" (camelize .Name) }}
{{- $flagNameVar := printf "%vFlagName" (camelize .Name )}}
{{- if or (eq .GoType "int64") (eq .GoType "int32") (eq .GoType "string") (eq .GoType "float64") (eq .GoType "float32") (eq .GoType "bool") }}
{{ template "flagnamevar" . }}
{{ $flagValueVar }}, err := cmd.Flags().Get{{pascalize .GoType}}({{ $flagNameVar }})
{{ flagValueVar .Name }}, err := cmd.Flags().Get{{pascalize .GoType}}({{ flagNameVar .Name }})
if err != nil{
return err, false
}
{{- /* reciever by convention is m for CLI */}}
m.{{ pascalize .Name }} = {{- if .IsNullable }}&{{- end }}{{ $flagValueVar }}
m.{{ pascalize .Name }} = {{- if .IsNullable }}&{{- end }}{{ flagValueVar .Name }}
{{- else if or (eq .GoType "strfmt.DateTime") (eq .GoType "strfmt.ObjectId") (eq .GoType "strfmt.UUID" ) }} {{/*Get flag value as string, then parse it*/}}
{{/*Many of the strfmt types can be added here*/}}
{{ template "flagnamevar" . }}
{{ $flagValueVar }}Str, err := cmd.Flags().GetString({{ $flagNameVar }})
{{ flagValueVar .Name }}Str, err := cmd.Flags().GetString({{ flagNameVar .Name }})
if err != nil{
return err, false
}
var {{ $flagValueVar }} {{ .GoType }}
if err := {{ $flagValueVar }}.UnmarshalText([]byte({{ $flagValueVar }}Str)); err != nil{
var {{ flagValueVar .Name }} {{ .GoType }}
if err := {{ flagValueVar .Name }}.UnmarshalText([]byte({{ flagValueVar .Name }}Str)); err != nil{
return err, false
}
m.{{ pascalize .Name }} = {{- if .IsNullable }}&{{- end }}{{ $flagValueVar }}
m.{{ pascalize .Name }} = {{- if .IsNullable }}&{{- end }}{{ flagValueVar .Name }}
{{- else }}
// warning: primitive {{.Name}} {{.GoType }} is not supported by go-swagger cli yet
{{- end }}
{{ end }}
{{ define "arrayretriever" }}
{{- $flagValueVar := printf "%vFlagValues" (camelize .Name) }}
{{- $flagNameVar := printf "%vFlagName" (camelize .Name )}}
{{- if or (eq .GoType "[]int64") (eq .GoType "[]int32") (eq .GoType "[]string") (eq .GoType "[]float64") (eq .GoType "[]float32") (eq .GoType "[]bool") }}
{{ template "flagnamevar" . }}
{{ $flagValueVar }}, err := cmd.Flags().Get{{pascalize .GoType}}Slice({{ $flagNameVar }})
{{ flagValueVar .Name }}, err := cmd.Flags().Get{{pascalize .GoType}}Slice({{ flagNameVar .Name }})
if err != nil{
return err, false
}
{{- /* reciever by convention is m for CLI */}}
m.{{ pascalize .Name }} = {{ $flagValueVar }}
{{- /* receiver by convention is m for CLI */}}
m.{{ pascalize .Name }} = {{ flagValueVar .Name }}
{{- else if or (eq .GoType "[]strfmt.DateTime") (eq .GoType "[]strfmt.ObjectId") (eq .GoType "[]strfmt.UUID") }} {{/*Get flag value as string, then parse it*/}}
{{ template "flagnamevar" . }}
{{ $flagValueVar }}Str, err := cmd.Flags().GetStringSlice({{ $flagNameVar }})
{{ flagValueVar .Name }}Str, err := cmd.Flags().GetStringSlice({{ flagNameVar .Name }})
if err != nil{
return err, false
}
{{ $flagValueVar }} := make({{ .GoType }}, len({{ $flagValueVar }}Str))
for i, v := range {{ $flagValueVar }}Str {
if err := {{ $flagValueVar }}[i].UnmarshalText([]byte(v)); err != nil{
{{ flagValueVar .Name }} := make({{ .GoType }}, len({{ flagValueVar .Name }}Str))
for i, v := range {{ flagValueVar .Name }}Str {
if err := {{ flagValueVar .Name }}[i].UnmarshalText([]byte(v)); err != nil{
return err, false
}
}
m.{{ pascalize .Name }} = {{- if .IsNullable }}&{{- end }}{{ $flagValueVar }}
m.{{ pascalize .Name }} = {{- if .IsNullable }}&{{- end }}{{ flagValueVar .Name }}
{{- else }}
// warning: array {{.Name}} {{.GoType }} is not supported by go-swagger cli yet
{{- end }}
{{ end }}
{{ end }}

View file

@ -14,12 +14,12 @@
{{- if .IsPrimitive }}
{{ template "primitiveregistrator" . }}
{{- else if .IsArray }}
// warning: {{.Name}} {{ .GoType }} array type is not supported by go-swagger cli yet
// warning: {{.Name}} {{ .GoType }} array type is not supported by go-swagger cli yet
{{- else if .IsMap }}
// warning: {{.Name}} {{ .GoType }} map type is not supported by go-swagger cli yet
{{- else if .IsComplexObject }} {{/* struct case */}}
{{ template "flagnamevar" . }}
if err := registerModel{{pascalize (dropPackage .GoType) }}Flags(depth + 1, {{ camelize .Name }}FlagName, cmd); err != nil{
if err := registerModel{{pascalize (dropPackage .GoType) }}Flags(depth + 1, {{ flagNameVar .Name }}, cmd); err != nil{
return err
}
{{- else }}
@ -28,10 +28,8 @@
{{ end }}
{{ define "propertyretriever" }}
{{- $flagNameVar := printf "%vFlagName" (camelize .Name) }}
{{- $flagValueVar := printf "%vFlagValue" (camelize .Name) }}
{{ $flagNameVar }} := fmt.Sprintf("%v.{{ .Name }}", cmdPrefix)
if cmd.Flags().Changed({{ $flagNameVar }}) {
{{ flagNameVar .Name }} := fmt.Sprintf("%v.{{ .Name }}", cmdPrefix)
if cmd.Flags().Changed({{ flagNameVar .Name }}) {
{{- if .IsPrimitive }}
{{ template "primitiveretriever" . }}
retAdded = true
@ -46,18 +44,18 @@
{{- end }}
}
{{- if and .IsComplexObject (not .IsArray) (not .IsMap) (not .IsStream) }}
{{ $flagValueVar }} := m.{{pascalize .Name}}
if swag.IsZero({{ $flagValueVar }}){
{{ $flagValueVar }} = {{if .IsNullable }}&{{end}}{{if containsPkgStr .GoType}}{{ .GoType }}{{else}}{{ .Pkg }}.{{.GoType}}{{ end }}{}
{{ flagValueVar .Name }} := m.{{pascalize .Name}}
if swag.IsZero({{ flagValueVar .Name }}){
{{ flagValueVar .Name }} = {{if .IsNullable }}&{{end}}{{if containsPkgStr .GoType}}{{ .GoType }}{{else}}{{ .Pkg }}.{{.GoType}}{{ end }}{}
}
{{/* always lift the payload to pointer and pass to model retrieve function. If .GoType has pkg str, use it, else use .Pkg+.GoType */}}
err, {{camelize .Name }}Added := retrieveModel{{pascalize (dropPackage .GoType) }}Flags(depth + 1, {{if not .IsNullable }}&{{end}}{{ $flagValueVar }}, {{ $flagNameVar }}, cmd)
err, {{pascalize .Name }}Added := retrieveModel{{pascalize (dropPackage .GoType) }}Flags(depth + 1, {{if not .IsNullable }}&{{end}}{{ flagValueVar .Name }}, {{ flagNameVar .Name }}, cmd)
if err != nil{
return err, false
}
retAdded = retAdded || {{camelize .Name }}Added
if {{camelize .Name }}Added {
m.{{pascalize .Name}} = {{ $flagValueVar }}
retAdded = retAdded || {{pascalize .Name }}Added
if {{pascalize .Name }}Added {
m.{{pascalize .Name}} = {{ flagValueVar .Name }}
}
{{- end }}
{{ end }}
@ -85,14 +83,14 @@ func registerModel{{pascalize .Name}}Flags(depth int, cmdPrefix string, cmd *cob
// register anonymous fields for {{.Name}}
{{ $anonName := .Name }}
{{ range .Properties }}
if err := register{{ pascalize $modelName }}Anon{{pascalize $anonName }}{{ pascalize .Name }}(depth, cmdPrefix, cmd); err != nil{
if err := register{{ pascalize $modelName }}PropAnon{{pascalize $anonName }}{{ pascalize .Name }}(depth, cmdPrefix, cmd); err != nil{
return err
}
{{ end }}
{{ end }}
{{ end }}
{{ range .Properties }}
if err := register{{ pascalize $modelName }}{{ pascalize .Name }}(depth, cmdPrefix, cmd); err != nil{
if err := register{{ pascalize $modelName }}Prop{{ pascalize .Name }}(depth, cmdPrefix, cmd); err != nil{
return err
}
{{ end }}
@ -104,7 +102,7 @@ func registerModel{{pascalize .Name}}Flags(depth int, cmdPrefix string, cmd *cob
// inline definition name {{ .Name }}, type {{.GoType}}
{{ $anonName := .Name }}
{{ range .Properties }}
func register{{ pascalize $modelName }}Anon{{pascalize $anonName }}{{ pascalize .Name }}(depth int, cmdPrefix string, cmd *cobra.Command) error {
func register{{ pascalize $modelName }}PropAnon{{pascalize $anonName }}{{ pascalize .Name }}(depth int, cmdPrefix string, cmd *cobra.Command) error {
if depth > maxDepth {
return nil
}
@ -117,7 +115,7 @@ func register{{ pascalize $modelName }}Anon{{pascalize $anonName }}{{ pascalize
{{/*register functions for each fields in this model */}}
{{ range .Properties }}
func register{{ pascalize $modelName }}{{ pascalize .Name }}(depth int, cmdPrefix string, cmd *cobra.Command) error{
func register{{ pascalize $modelName }}Prop{{ pascalize .Name }}(depth int, cmdPrefix string, cmd *cobra.Command) error{
if depth > maxDepth {
return nil
}
@ -133,11 +131,11 @@ func retrieveModel{{pascalize $modelName }}Flags(depth int, m *{{if containsPkgS
{{- if not .IsAnonymous }}{{/* named type composition */}}
{{ if or .IsPrimitive .IsComplexObject }}
// retrieve model {{.GoType}}
err, {{camelize .Name }}Added := retrieveModel{{ pascalize (dropPackage .GoType) }}Flags(depth, &m.{{pascalize (dropPackage .GoType) }}, cmdPrefix, cmd)
err, {{pascalize .Name }}Added := retrieveModel{{ pascalize (dropPackage .GoType) }}Flags(depth, &m.{{pascalize (dropPackage .GoType) }}, cmdPrefix, cmd)
if err != nil{
return err, false
}
retAdded = retAdded || {{camelize .Name }}Added
retAdded = retAdded || {{pascalize .Name }}Added
{{ else }} {{/*inline anonymous case*/}}
{{ end }}
@ -145,20 +143,20 @@ func retrieveModel{{pascalize $modelName }}Flags(depth int, m *{{if containsPkgS
// retrieve allOf {{.Name}} fields
{{ $anonName := .Name }}
{{ range .Properties }}
err, {{camelize .Name}}Added := retrieve{{ pascalize $modelName }}Anon{{pascalize $anonName }}{{ pascalize .Name }}Flags(depth, m, cmdPrefix, cmd)
err, {{pascalize .Name}}Added := retrieve{{ pascalize $modelName }}PropAnon{{pascalize $anonName }}{{ pascalize .Name }}Flags(depth, m, cmdPrefix, cmd)
if err != nil{
return err, false
}
retAdded = retAdded || {{ camelize .Name }}Added
retAdded = retAdded || {{ pascalize .Name }}Added
{{ end }}
{{- end }}
{{ end }}
{{ range .Properties }}
err, {{ camelize .Name }}Added := retrieve{{pascalize $modelName }}{{pascalize .Name }}Flags(depth, m, cmdPrefix, cmd)
err, {{ pascalize .Name }}Added := retrieve{{pascalize $modelName }}Prop{{pascalize .Name }}Flags(depth, m, cmdPrefix, cmd)
if err != nil{
return err, false
}
retAdded = retAdded || {{ camelize .Name }}Added
retAdded = retAdded || {{ pascalize .Name }}Added
{{ end }}
return nil, retAdded
}
@ -168,7 +166,7 @@ func retrieveModel{{pascalize $modelName }}Flags(depth int, m *{{if containsPkgS
// define retrieve functions for fields for inline definition name {{ .Name }}
{{ $anonName := .Name }}
{{ range .Properties }} {{/*anonymous fields will be registered directly on parent model*/}}
func retrieve{{ pascalize $modelName }}Anon{{pascalize $anonName }}{{ pascalize .Name }}Flags(depth int, m *{{if containsPkgStr $modelType}}{{ $modelType }}{{else}}{{ $modelPkg }}.{{$modelType}}{{ end }},cmdPrefix string, cmd *cobra.Command) (error,bool) {
func retrieve{{ pascalize $modelName }}PropAnon{{pascalize $anonName }}{{ pascalize .Name }}Flags(depth int, m *{{if containsPkgStr $modelType}}{{ $modelType }}{{else}}{{ $modelPkg }}.{{$modelType}}{{ end }},cmdPrefix string, cmd *cobra.Command) (error,bool) {
if depth > maxDepth {
return nil, false
}
@ -181,7 +179,7 @@ func retrieve{{ pascalize $modelName }}Anon{{pascalize $anonName }}{{ pascalize
{{ end }}
{{ range .Properties }}
func retrieve{{pascalize $modelName }}{{pascalize .Name }}Flags(depth int, m *{{if $modelPkg}}{{$modelPkg}}.{{ dropPackage $modelType }}{{else}}{{ $modelType }}{{end}}, cmdPrefix string, cmd *cobra.Command) (error, bool) {
func retrieve{{pascalize $modelName }}Prop{{pascalize .Name }}Flags(depth int, m *{{if $modelPkg}}{{$modelPkg}}.{{ dropPackage $modelType }}{{else}}{{ $modelType }}{{end}}, cmdPrefix string, cmd *cobra.Command) (error, bool) {
if depth > maxDepth {
return nil, false
}
@ -190,4 +188,4 @@ func retrieve{{pascalize $modelName }}{{pascalize .Name }}Flags(depth int, m *{{
return nil, retAdded
}
{{ end }} {{/*properties*/}}
{{ end }} {{/*define*/}}
{{ end }} {{/*define*/}}

View file

@ -16,6 +16,7 @@ import (
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
httptransport "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
@ -29,6 +30,31 @@ func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientServi
return &Client{transport: transport, formats: formats}
}
// New creates a new {{ humanize .Name }} API client with basic auth credentials.
// It takes the following parameters:
// - host: http host (github.com).
// - basePath: any base path for the API client ("/v1", "/v3").
// - scheme: http scheme ("http", "https").
// - user: user for basic authentication header.
// - password: password for basic authentication header.
func NewClientWithBasicAuth(host, basePath, scheme, user, password string) ClientService {
transport := httptransport.New(host, basePath, []string{scheme})
transport.DefaultAuthentication = httptransport.BasicAuth(user, password)
return &Client{transport: transport, formats: strfmt.Default}
}
// New creates a new {{ humanize .Name }} API client with a bearer token for authentication.
// It takes the following parameters:
// - host: http host (github.com).
// - basePath: any base path for the API client ("/v1", "/v3").
// - scheme: http scheme ("http", "https").
// - bearerToken: bearer token for Bearer authentication header.
func NewClientWithBearerToken(host, basePath, scheme, bearerToken string) ClientService {
transport := httptransport.New(host, basePath, []string{scheme})
transport.DefaultAuthentication = httptransport.BearerToken(bearerToken)
return &Client{transport: transport, formats: strfmt.Default}
}
/*
Client {{ if .Summary }}{{ .Summary }}{{ if .Description }}
@ -39,9 +65,58 @@ type Client struct {
formats strfmt.Registry
}
// ClientOption is the option for Client methods
// ClientOption may be used to customize the behavior of Client methods.
type ClientOption func(*runtime.ClientOperation)
{{- with .ClientOptions }}{{/* use ad'hoc function mediaGoName rather than pascalize because of patterns with * */}}
// This client is generated with a few options you might find useful for your swagger spec.
//
// Feel free to add you own set of options.
{{- if gt (len .ConsumesMediaTypes) 1 }}
// WithContentType allows the client to force the Content-Type header
// to negotiate a specific Consumer from the server.
//
// You may use this option to set arbitrary extensions to your MIME media type.
func WithContentType(mime string) ClientOption {
return func(r *runtime.ClientOperation) {
r.ConsumesMediaTypes = []string{mime}
}
}
{{ range .ConsumesMediaTypes }}
{{- if not ( eq (mediaGoName .) "" ) }}{{/* guard: in case garbled input produces a (conflicting) empty name */}}
// WithContentType{{ mediaGoName . }} sets the Content-Type header to {{ printf "%q" . }}.
func WithContentType{{ mediaGoName . }}(r *runtime.ClientOperation) {
r.ConsumesMediaTypes = []string{ {{ printf "%q" . }} }
}
{{- end }}
{{- end }}
{{- end }}
{{- if gt (len .ProducesMediaTypes) 1 }}
// WithAccept allows the client to force the Accept header
// to negotiate a specific Producer from the server.
//
// You may use this option to set arbitrary extensions to your MIME media type.
func WithAccept(mime string) ClientOption {
return func(r *runtime.ClientOperation) {
r.ProducesMediaTypes = []string{mime}
}
}
{{ range .ProducesMediaTypes }}
{{- if not ( eq (mediaGoName .) "" ) }}{{/* guard: in case garbled input produces a (conflicting) empty name */}}
// WithAccept{{ mediaGoName . }} sets the Accept header to {{ printf "%q" . }}.
func WithAccept{{ mediaGoName . }}(r *runtime.ClientOperation) {
r.ProducesMediaTypes = []string{ {{ printf "%q" . }} }
}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
// ClientService is the interface for Client methods
type ClientService interface {
{{ range .Operations }}
@ -124,4 +199,4 @@ func (a *Client) {{ pascalize .Name }}(params *{{ pascalize .Name }}Params{{ if
// SetTransport changes the transport on the client
func (a *Client) SetTransport(transport runtime.ClientTransport) {
a.transport = transport
}
}

View file

@ -119,11 +119,17 @@ func ({{ .ReceiverName }} *{{ pascalize .Name }}) Code() int {
}
func ({{ .ReceiverName }} *{{ pascalize .Name }}) Error() string {
return fmt.Sprintf("[{{ upper .Method }} {{ .Path }}][%d] {{ if .Name }}{{ .Name }} {{ else }}unknown error {{ end }}{{ if .Schema }} %+v{{ end }}", {{ if eq .Code -1 }}{{ .ReceiverName }}._statusCode{{ else }}{{ .Code }}{{ end }}{{ if .Schema }}, o.Payload{{ end }})
{{- if .Schema }}{{ if (not .Schema.IsStream) }}
payload, _ := json.Marshal(o.Payload)
{{- end }}{{- end }}
return fmt.Sprintf("[{{ upper .Method }} {{ .Path }}][%d]{{ if .Name }} {{ .Name }}{{ else }} unknown error{{ end }}{{ if .Schema }}{{ if not .Schema.IsStream }} %s{{ end }}{{ end }}", {{ if eq .Code -1 }}{{ .ReceiverName }}._statusCode{{ else }}{{ .Code }}{{ end }}{{ if .Schema }}{{ if not .Schema.IsStream }}, payload{{ end }}{{ end }})
}
func ({{ .ReceiverName }} *{{ pascalize .Name }}) String() string {
return fmt.Sprintf("[{{ upper .Method }} {{ .Path }}][%d] {{ if .Name }}{{ .Name }} {{ else }}unknown response {{ end }}{{ if .Schema }} %+v{{ end }}", {{ if eq .Code -1 }}{{ .ReceiverName }}._statusCode{{ else }}{{ .Code }}{{ end }}{{ if .Schema }}, o.Payload{{ end }})
{{- if .Schema }}{{ if (not .Schema.IsStream) }}
payload, _ := json.Marshal(o.Payload)
{{- end }}{{- end }}
return fmt.Sprintf("[{{ upper .Method }} {{ .Path }}][%d]{{ if .Name }} {{ .Name }}{{ else }} unknown response{{ end }}{{ if .Schema }}{{ if not .Schema.IsStream }} %s{{ end }}{{ end }}", {{ if eq .Code -1 }}{{ .ReceiverName }}._statusCode{{ else }}{{ .Code }}{{ end }}{{ if .Schema }}{{ if not .Schema.IsStream }}, payload{{ end }}{{ end }})
}
{{ if .Schema }}

View file

@ -71,7 +71,7 @@ type PetAPI interface {
PetUpdate(ctx context.Context, params pet.PetUpdateParams) middleware.Responder
}
//go:generate mockery -name StoreAPI -inpkg
//go:generate mockery --name StoreAPI --inpackage
// StoreAPI
type StoreAPI interface {

View file

@ -29,7 +29,7 @@ type contextKey string
const AuthKey contextKey = "Auth"
{{ range .OperationGroups -}}
//go:generate mockery -name {{ pascalize .Name}}API -inpkg
//go:generate mockery --name {{ pascalize .Name}}API --inpackage
/* {{ pascalize .Name }}API {{ .Description }} */
type {{ pascalize .Name }}API interface {

View file

@ -10,13 +10,13 @@
{{- else }}
{{- humanize .Name }}
{{- end }}
{{- if or .MinProperties .MinProperties }}
{{- if or .MinProperties .MaxProperties }}
//
{{- if .MinProperties }}
// Min Properties: {{ .MinProperties }}
// MinProperties: {{ .MinProperties }}
{{- end }}
{{- if .MaxProperties }}
// Max Properties: {{ .MaxProperties }}
// MaxProperties: {{ .MaxProperties }}
{{- end }}
{{- end }}
{{- if .Example }}

View file

@ -2,18 +2,18 @@
{{- with .ExternalDocs }}
{{- if .URL }}
{{- if .Description }}
> [{{ trimSpace .Description }}]({{ .URL }})
> [{{ mdBlock .Description }}]({{ .URL }})
{{- else }}
> [Read more]({{ .URL }})
{{- end }}
{{- else }}
> {{ trimSpace .Description }}
> {{ mdBlock .Description }}
{{- end }}
{{- end }}
{{- end }}
{{- define "docParam" }}{{/* renders a parameter with simple schema */}}
| {{ .Name }} | `{{ .Location }}` | {{ paramDocType . }} | `{{ .GoType }}` | {{ if .CollectionFormat }}`{{ docCollectionFormat .CollectionFormat .Child }}`{{ end }} | {{ if .Required }}{{ end }} | {{ if .Default }}`{{ json .Default }}`{{ end }} | {{ trimSpace .Description }} |
| {{ .Name }} | `{{ .Location }}` | {{ paramDocType . }} | `{{ .GoType }}` | {{ if .CollectionFormat }}`{{ docCollectionFormat .CollectionFormat .Child }}`{{ end }} | {{ if .Required }}{{ end }} | {{ if .Default }}`{{ json .Default }}`{{ end }} | {{ mdBlock .Description }} |
{{- end }}
{{- define "docModelSchema" }}{{/* renders a schema */}}
@ -46,7 +46,7 @@
{{- else if and .IsAliased .IsPrimitive (not .IsSuperAlias) -}}
| Name | Type | Go type | Default | Description | Example |
|------|------|---------| ------- |-------------|---------|
| {{ .Name }} | {{ schemaDocType . }}| {{ .AliasedType }} | {{ if .Default }}`{{ json .Default }}`{{ end }}| {{ trimSpace .Description }} | {{ if .Example }}`{{ .Example }}`{{ end }} |
| {{ .Name }} | {{ schemaDocType . }}| {{ .AliasedType }} | {{ if .Default }}`{{ json .Default }}`{{ end }}| {{ mdBlock .Description }} | {{ if .Example }}`{{ .Example }}`{{ end }} |
{{ printf "\n" }}
{{- else if or (and .IsAliased (not (.IsAdditionalProperties))) (and .IsComplexObject (not .Properties) (not .AllOf)) -}}
[{{- dropPackage .GoType }}](#{{ dasherize (dropPackage .GoType) -}})
@ -71,7 +71,7 @@ any
| Name | Type | Go type | Required | Default | Description | Example |
|------|------|---------|:--------:| ------- |-------------|---------|
{{- range .Properties }}
| {{ .Name }} | {{ template "docSchemaSimple" . }}| `{{ .GoType }}` | {{ if .Required }}{{ end }} | {{ if .Default }}`{{ json .Default }}`{{ end }}| {{ trimSpace .Description }} | {{ if .Example }}`{{ .Example }}`{{ end }} |
| {{ .Name }} | {{ template "docSchemaSimple" . }}| `{{ .GoType }}` | {{ if .Required }}{{ end }} | {{ if .Default }}`{{ json .Default }}`{{ end }}| {{ mdBlock .Description }} | {{ if .Example }}`{{ .Example }}`{{ end }} |
{{- end }}
{{ printf "\n" }}
{{- end }}
@ -86,7 +86,7 @@ any
| Type | Go type | Default | Description | Example |
|------|---------| ------- |-------------|---------|
| {{ template "docSchemaSimple" . }} | `{{ .GoType }}` |{{ if .Default }}`{{ json .Default }}`{{ end }}| {{ trimSpace .Description }} | {{ if .Example }}`{{ .Example }}`{{ end }} |
| {{ template "docSchemaSimple" . }} | `{{ .GoType }}` |{{ if .Default }}`{{ json .Default }}`{{ end }}| {{ mdBlock .Description }} | {{ if .Example }}`{{ .Example }}`{{ end }} |
{{- else }}
{{ template "docModelSchema" . }}
@ -104,7 +104,7 @@ any
| Type | Go type | Default | Description | Example |
|------|---------| ------- |-------------|---------|
| {{ template "docSchemaSimple" . }} | `{{ .GoType }}` |{{ if .Default }}`{{ json .Default }}`{{ end }}| {{ trimSpace .Description }} | {{ if .Example }}`{{ .Example }}`{{ end }} |
| {{ template "docSchemaSimple" . }} | `{{ .GoType }}` |{{ if .Default }}`{{ json .Default }}`{{ end }}| {{ mdBlock .Description }} | {{ if .Example }}`{{ .Example }}`{{ end }} |
{{- else }}
{{ template "docModelSchema" . }}
@ -161,7 +161,7 @@ any
{{- end }}
{{- define "docModelBodyParam" }}{{/* layout for body param schema */}}
| {{ .Name }} | `body` | {{ template "docSchemaSimple" .Schema }} | `{{ .Schema.GoType }}` | | {{ if .Required }}{{ end }} | {{ if .Default }}`{{ json .Default }}`{{ end }}| {{ trimSpace .Description }} |
| {{ .Name }} | `body` | {{ template "docSchemaSimple" .Schema }} | `{{ .Schema.GoType }}` | | {{ if .Required }}{{ end }} | {{ if .Default }}`{{ json .Default }}`{{ end }}| {{ mdBlock .Description }} |
{{- end }}
{{- define "docHeaders" }}{{/* renders response headers */}}
@ -169,7 +169,7 @@ any
| Name | Type | Go type | Separator | Default | Description |
|------|------|---------|-----------|---------|-------------|
{{- range .Headers }}
| {{ .Name }} | {{ headerDocType . }} | `{{ .GoType }}` | {{ if .CollectionFormat }}`{{ docCollectionFormat .CollectionFormat .Child }}`{{ end }} | {{ if .Default }}`{{ json .Default }}`{{ end }} | {{ trimSpace .Description }} |
| {{ .Name }} | {{ headerDocType . }} | `{{ .GoType }}` | {{ if .CollectionFormat }}`{{ docCollectionFormat .CollectionFormat .Child }}`{{ end }} | {{ if .Default }}`{{ json .Default }}`{{ end }} | {{ mdBlock .Description }} |
{{- end }}
{{- end }}
{{- end }}
@ -350,7 +350,7 @@ Name | Description
{{- range .Operations }}
{{- $opname := .Name }}
### <span id="{{ dasherize .Name }}"></span> {{ if .Summary }}{{ trimSpace .Summary }}{{ else }}{{ humanize .Name }}{{ end }} (*{{ .Name }}*)
### <span id="{{ dasherize .Name }}"></span> {{ if .Summary }}{{ mdBlock .Summary }}{{ else }}{{ humanize .Name }}{{ end }} (*{{ .Name }}*)
```
{{ upper .Method }} {{ joinPath .BasePath .Path }}
@ -424,16 +424,16 @@ Name | Description
| Code | Status | Description | Has headers | Schema |
|------|--------|-------------|:-----------:|--------|
{{- range .Responses }}
| [{{.Code}}](#{{ dasherize $opname }}-{{ .Code }}) | {{ httpStatus .Code }} | {{ trimSpace .Description }} | {{ if .Headers }}{{ end }} | [schema](#{{ dasherize $opname }}-{{ .Code }}-schema) |
| [{{.Code}}](#{{ dasherize $opname }}-{{ .Code }}) | {{ httpStatus .Code }} | {{ mdBlock .Description }} | {{ if .Headers }}{{ end }} | [schema](#{{ dasherize $opname }}-{{ .Code }}-schema) |
{{- end }}
{{- with .DefaultResponse }}
| [default](#{{ dasherize $opname }}-default) | | {{ trimSpace .Description }} | {{ if .Headers }}{{ end }} | [schema](#{{ dasherize $opname }}-default-schema) |
| [default](#{{ dasherize $opname }}-default) | | {{ mdBlock .Description }} | {{ if .Headers }}{{ end }} | [schema](#{{ dasherize $opname }}-default-schema) |
{{- end }}
#### Responses
{{ range .Responses }}
##### <span id="{{ dasherize $opname }}-{{ .Code }}"></span> {{.Code}}{{ if .Description }} - {{ trimSpace .Description }}{{ end }}
##### <span id="{{ dasherize $opname }}-{{ .Code }}"></span> {{.Code}}{{ if .Description }} - {{ mdBlock .Description }}{{ end }}
Status: {{ httpStatus .Code }}
###### <span id="{{ dasherize $opname }}-{{ .Code }}-schema"></span> Schema
@ -462,7 +462,7 @@ Status: {{ httpStatus .Code }}
{{- with .DefaultResponse }}
##### <span id="{{ dasherize $opname }}-default"></span> Default Response
{{ trimSpace .Description }}
{{ mdBlock .Description }}
###### <span id="{{ dasherize $opname }}-default-schema"></span> Schema
{{- if .Schema }}

View file

@ -1,6 +1,6 @@
{{ define "primitivefieldcontextvalidator" }}
{{ if .ReadOnly }}
if err := validate.ReadOnly(ctx, {{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ 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 }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil{
return err
}
{{ end }}
@ -8,25 +8,25 @@
{{ define "primitivefieldvalidator" }}
{{ if .Required }}
{{- if and (eq .GoType "string") (not .IsNullable) }}
if err := validate.RequiredString({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsAliased }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if .IsAliased }}){{ end }}); err != nil {
if err := validate.RequiredString({{ path . }}, {{ printf "%q" .Location }}, {{ if .IsAliased }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if .IsAliased }}){{ end }}); err != nil {
{{- else }}
if err := validate.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ 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 }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
{{- end }}
return err
}
{{- end }}
{{ if .MinLength }}
if err := validate.MinLength({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ToString }}, {{.MinLength }}); err != nil {
if err := validate.MinLength({{ path . }}, {{ printf "%q" .Location }}, {{ .ToString }}, {{.MinLength }}); err != nil {
return err
}
{{- end }}
{{ if .MaxLength }}
if err := validate.MaxLength({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ToString }}, {{.MaxLength }}); err != nil {
if err := validate.MaxLength({{ path . }}, {{ printf "%q" .Location }}, {{ .ToString }}, {{.MaxLength }}); err != nil {
return err
}
{{ end }}
{{ if .Pattern }}
if err := validate.Pattern({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ToString }}, `{{ escapeBackticks .Pattern }}`); err != nil {
if err := validate.Pattern({{ path . }}, {{ printf "%q" .Location }}, {{ .ToString }}, `{{ escapeBackticks .Pattern }}`); err != nil {
return err
}
{{- end }}
@ -41,7 +41,7 @@
{{ end }}
{{ if .Enum }}
// value enum
if err := {{.ReceiverName }}.validate{{ pascalize .Name }}{{ .Suffix }}Enum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}); err != nil {
if err := {{.ReceiverName }}.validate{{ pascalize .Name }}{{ .Suffix }}Enum({{ path . }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}); err != nil {
return err
}
{{- end }}
@ -52,7 +52,7 @@
{{ define "slicecontextvalidator" }}
{{ if .ReadOnly }}
if err := validate.ReadOnly(ctx, {{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ 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 }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil{
return err
}
{{ end }}
@ -71,9 +71,9 @@
{{- end }}
if err := {{.ValueExpression }}.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
return ve.ValidateName({{ path . }})
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
return ce.ValidateName({{ path . }})
}
return err
}
@ -86,7 +86,7 @@
{{define "slicevalidator" }}
{{ if .Required }}
if err := validate.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }}); err != nil {
if err := validate.Required({{ path . }}, {{ printf "%q" .Location }}, {{ .ValueExpression }}); err != nil {
return err
}
{{ end }}
@ -94,23 +94,23 @@
{{ .IndexVar }}{{ pascalize .Name }}Size := int64(len({{.ValueExpression }}))
{{ end }}
{{ if .MinItems }}
if err := validate.MinItems({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .IndexVar }}{{ pascalize .Name }}Size, {{.MinItems }}); err != nil {
if err := validate.MinItems({{ path . }}, {{ printf "%q" .Location }}, {{ .IndexVar }}{{ pascalize .Name }}Size, {{.MinItems }}); err != nil {
return err
}
{{ end }}
{{ if .MaxItems }}
if err := validate.MaxItems({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .IndexVar }}{{ pascalize .Name }}Size, {{.MaxItems }}); err != nil {
if err := validate.MaxItems({{ path . }}, {{ printf "%q" .Location }}, {{ .IndexVar }}{{ pascalize .Name }}Size, {{.MaxItems }}); err != nil {
return err
}
{{ end }}
{{ if .UniqueItems }}
if err := validate.UniqueItems({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil {
if err := validate.UniqueItems({{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil {
return err
}
{{ end }}
{{ if .Enum }}
// for slice
if err := {{.ReceiverName }}.validate{{ pascalize .Name }}Enum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil {
if err := {{.ReceiverName }}.validate{{ pascalize .Name }}Enum({{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil {
return err
}
{{ end }}
@ -138,9 +138,9 @@
{{- end }}
if err := {{.ValueExpression }}.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
return ve.ValidateName({{ path . }})
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
return ce.ValidateName({{ path . }})
}
return err
}
@ -154,10 +154,10 @@
{{- if and .Required }}
{{- if or .IsNullable .IsInterface }}
if {{ .ReceiverName }}.{{ pascalize .Name }} == nil {
return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, nil)
return errors.Required({{ path . }}, {{ printf "%q" .Location }}, nil)
}
{{- else }}
if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ 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 }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{ .ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
return err
}
{{- end }}
@ -213,7 +213,7 @@
{{ template "mapcontextvalidator" . }}
{{- else if and .IsMap .IsInterface }}
{{ if .Enum }}
if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}ValueEnum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}ValueEnum({{ path . }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
return err
}
{{- end }}
@ -278,10 +278,10 @@
{{- if and .Required }}
{{- if or .IsNullable .IsInterface }}
if {{ .ReceiverName }}.{{ pascalize .Name }} == nil {
return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, nil)
return errors.Required({{ path . }}, {{ printf "%q" .Location }}, nil)
}
{{- else }}
if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ 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 }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{ .ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
return err
}
{{- end }}
@ -295,12 +295,12 @@
{{- if .IsInterface }}
if {{ $validatedValues }}[{{ $keyVar }}] == nil { // not required
{{- else }}
if swag.IsZero({{ $validatedValues }}[{{ $keyVar }}]) { // not required
if swag.IsZero({{ .ValueExpression }}) { // not required
{{- end }}
continue
}
{{- else if and (.Required) (not .IsArray) }}{{/* Required slice is processed below */}}
if err := validate.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
if err := validate.Required({{ path . }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
return err
}
{{- end }}
@ -313,9 +313,9 @@
{{- end }}
if err := val.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
return ve.ValidateName({{ path . }})
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
return ce.ValidateName({{ path . }})
}
return err
}
@ -342,7 +342,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 }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ 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 }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
return err
}
{{- end }}
@ -352,15 +352,16 @@
{{- else if .IsArray }}
{{ template "slicevalidator" . }}
{{- else if and .IsMap (not .IsInterface) }}
{{ template "minmaxProperties" .}}
{{ template "mapvalidator" . }}
{{ if .Enum }}
if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}ValueEnum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}ValueEnum({{ path . }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
return err
}
{{- end }}
{{- else if and .IsMap .IsInterface }}
{{ if .Enum }}
if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}ValueEnum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}ValueEnum({{ path . }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
return err
}
{{- end }}
@ -372,9 +373,9 @@
{{- end }}
if err := val.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
return ve.ValidateName({{ path . }})
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
return ce.ValidateName({{ path . }})
}
return err
}
@ -402,7 +403,7 @@
{{ end }}
{{ if .Enum }}
// from map
if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}Enum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }}); err != nil {
if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}Enum({{ path . }}, {{ printf "%q" .Location }}, {{ .ValueExpression }}); err != nil {
return err
}
{{ end }}
@ -430,6 +431,11 @@
{{- end }}
{{- end }}
{{- end }}
{{- else if .Enum }}
// from map without additionalProperties
if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}Enum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }}); err != nil {
return err
}
{{- end }}
{{ end }}
@ -462,9 +468,9 @@
{{ end }}
if err := {{.ValueExpression }}.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
return ve.ValidateName({{ path . }})
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
return ce.ValidateName({{ path . }})
}
return err
}
@ -490,14 +496,14 @@
{{ define "minmaxProperties" }}
{{- if and (or .IsMap (and .IsAdditionalProperties .HasAdditionalProperties)) (or .MinProperties .MaxProperties) }}
{{- if and (not .IsAdditionalProperties) (not .IsInterface) (eq (len .Properties) 0) }}{{/* map only */}}
nprops := len({{ if and (not .IsAliased) .HasAdditionalProperties }}{{ .ReceiverName }}{{ else }}{{ .ValueExpression }}{{ end }})
nprops := len({{ if and .IsMap (not .IsAliased) .HasAdditionalProperties (not .IsElem) (not .IsProperty) }}{{ .ReceiverName }}{{ else }}{{ .ValueExpression }}{{ end }})
{{- else }}{{/* object with properties */}}
{{- if and .IsNullable .MinProperties }}
{{- if gt0 .MinProperties }}
// short circuits minProperties > 0
if {{ .ReceiverName }} == nil {
return errors.TooFewProperties({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ .MinProperties }})
return errors.TooFewProperties({{ path . }}, {{ printf "%q" .Location }}, {{ .MinProperties }})
}
{{- end }}
{{- end }}
@ -517,13 +523,13 @@
{{ if .MinProperties }}
// minProperties: {{ .MinProperties }}
if nprops < {{ .MinProperties }} {
return errors.TooFewProperties({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ .MinProperties }})
return errors.TooFewProperties({{ path . }}, {{ printf "%q" .Location }}, {{ .MinProperties }})
}
{{- end }}
{{ if .MaxProperties }}
// maxProperties: {{ .MaxProperties }}
if nprops > {{ .MaxProperties }} {
return errors.TooManyProperties({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ .MaxProperties }})
return errors.TooManyProperties({{ path . }}, {{ printf "%q" .Location }}, {{ .MaxProperties }})
}
{{- end }}
{{- end }}
@ -548,7 +554,7 @@
*/}}
{{- if not .IsAnonymous }}
{{- if and .Required (or .IsNullable .IsBaseType .IsMap) }}
if err := validate.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil {
if err := validate.Required({{ path . }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil {
return err
}
{{- if and (not .Required) .IsBaseType }}
@ -563,9 +569,9 @@
{{- end }}
if err := {{.ValueExpression }}.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
return ve.ValidateName({{ path . }})
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
return ce.ValidateName({{ path . }})
}
return err
}
@ -602,7 +608,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 }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ 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 }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
return err
}
{{- end }}
@ -625,7 +631,7 @@
{{- if .IsPrimitive }}
{{- if .IsAliased }}
{{- if and .Required (not .IsAnonymous) }}
if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ 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 }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
return err
}
{{- end }}
@ -635,7 +641,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 }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ 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 }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
return err
}
{{- end }}
@ -651,10 +657,10 @@
{{- if and .IsAdditionalProperties .Required (not .IsAliased) }}
{{- if or .IsNullable .IsInterface }}
if {{ .ValueExpression }} == nil {
return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }})
return errors.Required({{ path . }}, {{ printf "%q" .Location }}, {{ .ValueExpression }})
}
{{- else }}
if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ 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 }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
return err
}
{{- end }}
@ -663,10 +669,10 @@
{{- else if and .IsExternal .Required }}
{{- if or .IsNullable .IsInterface }}
if {{ .ValueExpression }} == nil {
return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }})
return errors.Required({{ path . }}, {{ printf "%q" .Location }}, {{ .ValueExpression }})
}
{{- else }}
if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ 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 }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
return err
}
{{- end }}
@ -697,7 +703,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 }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ 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 }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
return err
}
{{- end }}
@ -1034,11 +1040,11 @@ func ({{.ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else i
{{- if and $.IsTuple .IsMap .Required }}
{{- if .IsInterface }}
if {{ .ValueExpression }} == nil {
return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }})
return errors.Required({{ path . }}, {{ printf "%q" .Location }}, {{ .ValueExpression }})
}
{{- else }}
if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}(
{{- if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }},
{{ path . }}, {{ printf "%q" .Location }},
{{- if and (eq .GoType "string") (not (or .IsAnonymous .IsNullable)) }}{{ .GoType }}({{ end }}
{{- .ValueExpression }}
{{- if and (eq .GoType "string") (not (or .IsAnonymous .IsNullable)) }}){{ end }}); err != nil {

View file

@ -230,7 +230,7 @@ type Server struct {
ListenLimit int{{ if .UseGoStructFlags }} `long:"listen-limit" description:"limit the number of outstanding requests"`{{ end }}
KeepAlive time.Duration{{ if .UseGoStructFlags }} `long:"keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)" default:"3m"`{{ end }}
ReadTimeout time.Duration{{ if .UseGoStructFlags }} `long:"read-timeout" description:"maximum duration before timing out read of the request" default:"30s"`{{ end }}
WriteTimeout time.Duration{{ if .UseGoStructFlags }} `long:"write-timeout" description:"maximum duration before timing out write of the response" default:"60s"`{{ end }}
WriteTimeout time.Duration{{ if .UseGoStructFlags }} `long:"write-timeout" description:"maximum duration before timing out write of the response" default:"30s"`{{ end }}
httpServerL net.Listener
TLSHost string{{ if .UseGoStructFlags }} `long:"tls-host" description:"the IP to listen on for tls, when not specified it's the same as --host" env:"TLS_HOST"`{{ end }}

View file

@ -1,3 +1,3 @@
if err := validate.FormatOf({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ printf "%q" .SwaggerFormat }}, {{ .ToString }}, formats); err != nil {
if err := validate.FormatOf({{ path . }}, {{ printf "%q" .Location }}, {{ printf "%q" .SwaggerFormat }}, {{ .ToString }}, formats); err != nil {
return err
}

View file

@ -1,21 +1,21 @@
{{- if or (hasPrefix .UnderlyingType "int") }}
{{- if and (hasPrefix .UnderlyingType "int64") (not .IsAliased) }}
if err := validate.MaximumInt({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.Maximum }}, {{.ExclusiveMaximum }}); err != nil {
if err := validate.MaximumInt({{ path . }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.Maximum }}, {{.ExclusiveMaximum }}); err != nil {
{{- else }}
if err := validate.MaximumInt({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, int64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.Maximum }}, {{.ExclusiveMaximum }}); err != nil {
if err := validate.MaximumInt({{ path . }}, {{ printf "%q" .Location }}, int64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.Maximum }}, {{.ExclusiveMaximum }}); err != nil {
{{- end }}
{{- else }}
{{- if hasPrefix .UnderlyingType "uint" }}
{{- if and (hasPrefix .UnderlyingType "uint64") (not .IsAliased) }}
if err := validate.MaximumUint({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.Maximum }}, {{.ExclusiveMaximum }}); err != nil {
if err := validate.MaximumUint({{ path . }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.Maximum }}, {{.ExclusiveMaximum }}); err != nil {
{{- else }}
if err := validate.MaximumUint({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, uint64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.Maximum }}, {{.ExclusiveMaximum }}); err != nil {
if err := validate.MaximumUint({{ path . }}, {{ printf "%q" .Location }}, uint64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.Maximum }}, {{.ExclusiveMaximum }}); err != nil {
{{- end }}
{{- else }}
{{- if and (eq .UnderlyingType "float64") (not .IsAliased) }}
if err := validate.Maximum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.Maximum }}, {{.ExclusiveMaximum }}); err != nil {
if err := validate.Maximum({{ path . }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.Maximum }}, {{.ExclusiveMaximum }}); err != nil {
{{- else }}
if err := validate.Maximum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, float64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.Maximum }}, {{.ExclusiveMaximum }}); err != nil {
if err := validate.Maximum({{ path . }}, {{ printf "%q" .Location }}, float64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.Maximum }}, {{.ExclusiveMaximum }}); err != nil {
{{- end }}
{{- end }}
{{- end }}

View file

@ -1,21 +1,21 @@
{{- if hasPrefix .UnderlyingType "int" }}
{{- if and (hasPrefix .UnderlyingType "int64") (not .IsAliased) }}
if err := validate.MinimumInt({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.Minimum }}, {{.ExclusiveMinimum }}); err != nil {
if err := validate.MinimumInt({{ path . }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.Minimum }}, {{.ExclusiveMinimum }}); err != nil {
{{- else }}
if err := validate.MinimumInt({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, int64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.Minimum }}, {{.ExclusiveMinimum }}); err != nil {
if err := validate.MinimumInt({{ path . }}, {{ printf "%q" .Location }}, int64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.Minimum }}, {{.ExclusiveMinimum }}); err != nil {
{{- end }}
{{- else }}
{{- if hasPrefix .UnderlyingType "uint" }}
{{- if and (hasPrefix .UnderlyingType "uint64") (not .IsAliased) }}
if err := validate.MinimumUint({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.Minimum }}, {{.ExclusiveMinimum }}); err != nil {
if err := validate.MinimumUint({{ path . }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.Minimum }}, {{.ExclusiveMinimum }}); err != nil {
{{- else }}
if err := validate.MinimumUint({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, uint64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.Minimum }}, {{.ExclusiveMinimum }}); err != nil {
if err := validate.MinimumUint({{ path . }}, {{ printf "%q" .Location }}, uint64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.Minimum }}, {{.ExclusiveMinimum }}); err != nil {
{{- end }}
{{- else }}
{{- if and (eq .UnderlyingType "float64") (not .IsAliased) }}
if err := validate.Minimum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.Minimum }}, {{.ExclusiveMinimum }}); err != nil {
if err := validate.Minimum({{ path . }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.Minimum }}, {{.ExclusiveMinimum }}); err != nil {
{{- else }}
if err := validate.Minimum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, float64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.Minimum }}, {{.ExclusiveMinimum }}); err != nil {
if err := validate.Minimum({{ path . }}, {{ printf "%q" .Location }}, float64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.Minimum }}, {{.ExclusiveMinimum }}); err != nil {
{{- end }}
{{- end }}
{{- end }}

View file

@ -1,21 +1,21 @@
{{- if and (hasPrefix .UnderlyingType "int") (isInteger .MultipleOf) }}{{/* if the type is an integer, but the multiple factor is not, fall back to the float64 version of the validator */}}
{{- if and (hasPrefix .UnderlyingType "int64") (not .IsAliased) }}
if err := validate.MultipleOfInt({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.MultipleOf }}); err != nil {
if err := validate.MultipleOfInt({{ path . }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.MultipleOf }}); err != nil {
{{- else }}
if err := validate.MultipleOfInt({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, int64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.MultipleOf }}); err != nil {
if err := validate.MultipleOfInt({{ path . }}, {{ printf "%q" .Location }}, int64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.MultipleOf }}); err != nil {
{{- end }}
{{- else }}
{{- if and (hasPrefix .UnderlyingType "uint") (isInteger .MultipleOf) }}
{{- if and (hasPrefix .UnderlyingType "uint64") (not .IsAliased) }}
if err := validate.MultipleOfUint({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.MultipleOf }}); err != nil {
if err := validate.MultipleOfUint({{ path . }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.MultipleOf }}); err != nil {
{{- else }}
if err := validate.MultipleOfUint({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, uint64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.MultipleOf }}); err != nil {
if err := validate.MultipleOfUint({{ path . }}, {{ printf "%q" .Location }}, uint64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.MultipleOf }}); err != nil {
{{- end }}
{{- else }}
{{- if and (eq .UnderlyingType "float64") (not .IsAliased) }}
if err := validate.MultipleOf({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.MultipleOf }}); err != nil {
if err := validate.MultipleOf({{ path . }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}, {{.MultipleOf }}); err != nil {
{{- else }}
if err := validate.MultipleOf({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, float64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.MultipleOf }}); err != nil {
if err := validate.MultipleOf({{ path . }}, {{ printf "%q" .Location }}, float64({{ if .IsNullable }}*{{ end }}{{.ValueExpression }}), {{.MultipleOf }}); err != nil {
{{- end }}
{{- end }}
{{- end }}

View file

@ -1,15 +1,15 @@
{{if .MinLength}}
if err := validate.MinLength({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ .ToString }}, {{.MinLength}}); err != nil {
if err := validate.MinLength({{ path . }}, {{ printf "%q" .Location }}, {{ .ToString }}, {{.MinLength}}); err != nil {
return err
}
{{end}}
{{if .MaxLength}}
if err := validate.MaxLength({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ .ToString }}, {{.MaxLength}}); err != nil {
if err := validate.MaxLength({{ path . }}, {{ printf "%q" .Location }}, {{ .ToString }}, {{.MaxLength}}); err != nil {
return err
}
{{end}}
{{if .Pattern}}
if err := validate.Pattern({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ .ToString }}, `{{escapeBackticks .Pattern}}`); err != nil {
if err := validate.Pattern({{ path . }}, {{ printf "%q" .Location }}, {{ .ToString }}, `{{escapeBackticks .Pattern}}`); err != nil {
return err
}
{{end}}
@ -23,7 +23,7 @@ if err := validate.Pattern({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf
{{ template "validationMultipleOf" . }}
{{end}}
{{if .Enum}}
if err := validate.EnumCase({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ 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 }}, {{ printf "%#v" .Enum}}, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
return err
}
{{end}}

View file

@ -40,14 +40,6 @@
// Min Items: {{ .MinItems }}
{{- end }}
{{- if .MinProperties }}
// Min Properties: {{ .MinProperties }}
{{- end }}
{{- if .MaxProperties }}
// Max Properties: {{ .MaxProperties }}
{{- end }}
{{- if .UniqueItems }}
// Unique: true
{{- end }}
@ -57,6 +49,6 @@
{{- end }}
{{- if .Enum }}
// Enum: {{ printf "%v" .Enum }}
// Enum: {{ json .Enum }}
{{- end }}
{{- end}}

View file

@ -345,7 +345,6 @@ func (t *typeResolver) inferAliasing(result *resolvedType, _ *spec.Schema, isAno
}
func (t *typeResolver) resolveFormat(schema *spec.Schema, isAnonymous bool, isRequired bool) (returns bool, result resolvedType, err error) {
if schema.Format != "" {
// defaults to string
result.SwaggerType = str
@ -401,7 +400,6 @@ func (t *typeResolver) resolveFormat(schema *spec.Schema, isAnonymous bool, isRe
//
// The interpretation of Required as a mean to make a type nullable is carried out elsewhere.
func (t *typeResolver) isNullable(schema *spec.Schema) bool {
if nullable, ok := t.isNullableOverride(schema); ok {
return nullable
}
@ -1000,8 +998,8 @@ func warnSkipValidation(types interface{}) func(string, interface{}) {
func guardValidations(tpe string, schema interface {
Validations() spec.SchemaValidations
SetValidations(spec.SchemaValidations)
}, types ...string) {
}, types ...string,
) {
v := schema.Validations()
if len(types) == 0 {
types = []string{tpe}
@ -1049,7 +1047,8 @@ func guardValidations(tpe string, schema interface {
func guardFormatConflicts(format string, schema interface {
Validations() spec.SchemaValidations
SetValidations(spec.SchemaValidations)
}) {
},
) {
v := schema.Validations()
msg := fmt.Sprintf("for format %q", format)