1
0

Task Attachments (#104)

This commit is contained in:
konrad
2019-10-16 20:52:29 +00:00
committed by Gitea
parent e2f481a6e5
commit 2169464983
349 changed files with 22540 additions and 5267 deletions

View File

@ -1,7 +1,10 @@
dist
testdata/simple*/docs
example/basic/docs/*
example/celler/docs/*
cover.out
# Test binary, build with `go test -c`
*.test
@ -12,3 +15,6 @@ cover.out
# Etc
.DS_Store
swag
swag.exe

View File

@ -2,13 +2,12 @@ language: go
sudo: false
go:
- 1.9.x
- 1.10.x
- 1.11.x
- 1.12.x
install:
- make install
- make deps
script:
- make fmt-check

View File

@ -3,14 +3,16 @@ GOLINT:=$(shell which golint)
GOIMPORT:=$(shell which goimports)
GOFMT:=$(shell which gofmt)
GOBUILD:=$(GOCMD) build
GOINSTALL:=$(GOCMD) install
GOCLEAN:=$(GOCMD) clean
GOTEST:=$(GOCMD) test
GOGET:=$(GOCMD) get
GOLIST:=$(GOCMD) list
GOVET:=$(GOCMD) vet
u := $(if $(update),-u)
BINARY_NAME:=swag
PACKAGES:=$(shell $(GOLIST) ./...)
PACKAGES:=$(shell $(GOLIST) github.com/swaggo/swag github.com/swaggo/swag/cmd/swag github.com/swaggo/swag/gen)
GOFILES:=$(shell find . -name "*.go" -type f)
export GO111MODULE := on
@ -18,8 +20,12 @@ export GO111MODULE := on
all: test build
.PHONY: build
build:
$(GOBUILD) -o $(BINARY_NAME) -v ./cmd/...
build: deps
$(GOBUILD) -o $(BINARY_NAME) ./cmd/swag
.PHONY: install
install: deps
$(GOINSTALL) ./cmd/swag
.PHONY: test
test:
@ -45,18 +51,25 @@ clean:
$(GOCLEAN)
rm -f $(BINARY_NAME)
.PHONY: install
install:
$(GOGET) -v ./...
.PHONY: deps
deps:
$(GOGET) ${u} -d
$(GOGET) github.com/stretchr/testify/assert
$(GOGET) github.com/alecthomas/template
.PHONY: devel-deps
devel-deps:
GO111MODULE=off $(GOGET) -v -u \
golang.org/x/lint/golint \
github.com/swaggo/swag/cmd/swag \
github.com/swaggo/swag/gen
.PHONY: lint
lint:
which golint || $(GOGET) -u golang.org/x/lint/golint
lint: devel-deps
for PKG in $(PACKAGES); do golint -set_exit_status $$PKG || exit 1; done;
.PHONY: vet
vet:
vet: deps devel-deps
$(GOVET) $(PACKAGES)
.PHONY: fmt

View File

@ -9,6 +9,7 @@
[![Go Doc](https://godoc.org/github.com/swaggo/swagg?status.svg)](https://godoc.org/github.com/swaggo/swag)
[![Backers on Open Collective](https://opencollective.com/swag/backers/badge.svg)](#backers)
[![Sponsors on Open Collective](https://opencollective.com/swag/sponsors/badge.svg)](#sponsors) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fswaggo%2Fswag.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fswaggo%2Fswag?ref=badge_shield)
[![Release](https://img.shields.io/github/release/swaggo/swag.svg?style=flat-square)](https://github.com/swaggo/swag/releases)
Swag converts Go annotations to Swagger Documentation 2.0. We've created a variety of plugins for popular [Go web frameworks](#supported-web-frameworks). This allows you to quickly integrate with an existing Go project (using Swagger UI).
@ -19,7 +20,7 @@ Swag converts Go annotations to Swagger Documentation 2.0. We've created a varie
- [How to use it with Gin](#how-to-use-it-with-gin)
- [Implementation Status](#implementation-status)
- [Declarative Comments Format](#declarative-comments-format)
- [General API Info](##general-api-info)
- [General API Info](#general-api-info)
- [API Operation](#api-operation)
- [Security](#security)
- [Examples](#examples)
@ -29,7 +30,7 @@ Swag converts Go annotations to Swagger Documentation 2.0. We've created a varie
- [Use multiple path params](#use-multiple-path-params)
- [Example value of struct](#example-value-of-struct)
- [Description of struct](#description-of-struct)
- [Override swagger type of a struct field](#Override-swagger-type-of-a-struct-field)
- [Use swaggertype tag to supported custom type](#use-swaggertype-tag-to-supported-custom-type)
- [Add extension info to struct field](#add-extension-info-to-struct-field)
- [How to using security annotations](#how-to-using-security-annotations)
- [About the Project](#about-the-project)
@ -42,6 +43,8 @@ Swag converts Go annotations to Swagger Documentation 2.0. We've created a varie
```sh
$ go get -u github.com/swaggo/swag/cmd/swag
```
To build from source you need [Go](https://golang.org/dl/) (1.9 or newer).
Or download the pre-compiled binaries binray form [release page](https://github.com/swaggo/swag/releases).
3. Run `swag init` in the project's root folder which contains the `main.go` file. This will parse your comments and generate the required files (`docs` folder and `docs/docs.go`).
@ -69,7 +72,8 @@ OPTIONS:
--dir value, -d value Directory you want to parse (default: "./")
--propertyStrategy value, -p value Property Naming Strategy like snakecase,camelcase,pascalcase (default: "camelcase")
--output value, -o value Output directory for al the generated files(swagger.json, swagger.yaml and doc.go) (default: "./docs")
--parseVendor Parse go files in 'vendor' folder, disabled by default --output value, -o value Output directory for al the generated files(swagger.json, swagger.yaml and doc.go) (default: "./docs")
--parseVendor Parse go files in 'vendor' folder, disabled by default
--parseDependency Parse go files in outside dependency folder, disabled by default
```
## Supported Web Frameworks
@ -86,7 +90,7 @@ Find the example source code [here](https://github.com/swaggo/swag/tree/master/e
1. After using `swag init` to generate Swagger 2.0 docs, import the following packages:
```go
import "github.com/swaggo/gin-swagger" // gin-swagger middleware
import "github.com/swaggo/gin-swagger/swaggerFiles" // swagger embed files
import "github.com/swaggo/files" // swagger embed files
```
2. Add [General API](#general-api-info) annotations in `main.go` code:
@ -134,6 +138,8 @@ import "github.com/swaggo/gin-swagger/swaggerFiles" // swagger embed files
// @authorizationurl https://example.com/oauth/authorize
// @scope.admin Grants read and write access to administrative information
// @x-extension-openapi {"example": "value on a json format"}
func main() {
r := gin.Default()
@ -165,9 +171,9 @@ package main
import (
"github.com/gin-gonic/gin"
"github.com/swaggo/files"
"github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
"./docs" // docs is generated by Swag CLI, you have to import it.
)
@ -188,7 +194,8 @@ func main() {
docs.SwaggerInfo.Version = "1.0"
docs.SwaggerInfo.Host = "petstore.swagger.io"
docs.SwaggerInfo.BasePath = "/v2"
docs.SwaggerInfo.Schemes = []string{"http", "https"}
r := gin.New()
// use ginSwagger middleware to serve the API docs
@ -309,7 +316,7 @@ $ swag init
| tag.name | Name of a tag.| // @tag.name This is the name of the tag |
| tag.description | Description of the tag | // @tag.description Cool Description |
| tag.docs.url | Url of the external Documentation of the tag | // @tag.docs.url https://example.com|
| tag.docs.descripiton | Description of the external Documentation of the tag| // @tag.docs.descirption Best example documentation |
| tag.docs.description | Description of the external Documentation of the tag| // @tag.docs.description Best example documentation |
| termsOfService | The Terms of Service for the API.| // @termsOfService http://swagger.io/terms/ |
| contact.name | The contact information for the exposed API.| // @contact.name API Support |
| contact.url | The URL pointing to the contact information. MUST be in the format of a URL. | // @contact.url http://www.swagger.io/support|
@ -319,6 +326,21 @@ $ swag init
| host | The host (name or ip) serving the API. | // @host localhost:8080 |
| BasePath | The base path on which the API is served. | // @BasePath /api/v1 |
| schemes | The transfer protocol for the operation that separated by spaces. | // @schemes http https |
| x-name | The extension key, must be start by x- and take only json value | // @x-example-key {"key": "value"} |
### Using markdown descriptions
When a short string in your documentation is insufficient, or you need images, code examples and things like that you may want to use markdown descriptions. In order to use markdown descriptions use the following annotations.
| annotation | description | example |
|-------------|--------------------------------------------|---------------------------------|
| title | **Required.** The title of the application.| // @title Swagger Example API |
| version | **Required.** Provides the version of the application API.| // @version 1.0 |
| description.markdown | A short description of the application. Parsed from the api.md file. This is an alternative to @description |// @description.markdown No value needed, this parses the description from api.md |
| tag.name | Name of a tag.| // @tag.name This is the name of the tag |
| tag.description.markdown | Description of the tag this is an alternative to tag.description. The description will be read from a file named like tagname.md | // @tag.description.markdown |
## API Operation
@ -326,20 +348,21 @@ $ swag init
[celler/controller](https://github.com/swaggo/swag/tree/master/example/celler/controller)
| annotation | description |
|--------------------|----------------------------------------------------------------------------------------------------------------------------|
| description | A verbose explanation of the operation behavior. |
| id | A unique string used to identify the operation. Must be unique among all API operations. |
| tags | A list of tags to each API operation that separated by commas. |
| summary | A short summary of what the operation does. |
| accept | A list of MIME types the APIs can consume. Value MUST be as described under [Mime Types](#mime-types). |
| produce | A list of MIME types the APIs can produce. Value MUST be as described under [Mime Types](#mime-types). |
| param | Parameters that separated by spaces. `param name`,`param type`,`data type`,`is mandatory?`,`comment` `attribute(optional)` |
| security | [Security](#security) to each API operation. |
| success | Success response that separated by spaces. `return code`,`{param type}`,`data type`,`comment` |
| failure | Failure response that separated by spaces. `return code`,`{param type}`,`data type`,`comment` |
| header | Header in response that separated by spaces. `return code`,`{param type}`,`data type`,`comment` |
| router | Path definition that separated by spaces. `path`,`[httpMethod]` |
| annotation | description |
|-------------|----------------------------------------------------------------------------------------------------------------------------|
| description | A verbose explanation of the operation behavior. |
| id | A unique string used to identify the operation. Must be unique among all API operations. |
| tags | A list of tags to each API operation that separated by commas. |
| summary | A short summary of what the operation does. |
| accept | A list of MIME types the APIs can consume. Value MUST be as described under [Mime Types](#mime-types). |
| produce | A list of MIME types the APIs can produce. Value MUST be as described under [Mime Types](#mime-types). |
| param | Parameters that separated by spaces. `param name`,`param type`,`data type`,`is mandatory?`,`comment` `attribute(optional)` |
| security | [Security](#security) to each API operation. |
| success | Success response that separated by spaces. `return code`,`{param type}`,`data type`,`comment` |
| failure | Failure response that separated by spaces. `return code`,`{param type}`,`data type`,`comment` |
| header | Header in response that separated by spaces. `return code`,`{param type}`,`data type`,`comment` |
| router | Path definition that separated by spaces. `path`,`[httpMethod]` |
| x-name | The extension key, must be start by x- and take only json value. |
## Mime Types
@ -365,12 +388,11 @@ Besides that, `swag` also accepts aliases for some MIME Types as follows:
## Param Type
- object (struct)
- string (string)
- integer (int, uint, uint32, uint64)
- number (float32)
- boolean (bool)
- array
- query
- path
- header
- body
- formData
## Data Type
@ -508,7 +530,8 @@ type Account struct {
}
```
### Override swagger type of a struct field
### Use swaggertype tag to supported custom type
[#201](https://github.com/swaggo/swag/issues/201#issuecomment-475479409)
```go
type TimestampTime struct {
@ -544,6 +567,33 @@ type Account struct {
}
```
[#379](https://github.com/swaggo/swag/issues/379)
```go
type CerticateKeyPair struct {
Crt []byte `json:"crt" swaggertype:"string" format:"base64" example:"U3dhZ2dlciByb2Nrcw=="`
Key []byte `json:"key" swaggertype:"string" format:"base64" example:"U3dhZ2dlciByb2Nrcw=="`
}
```
generated swagger doc as follows:
```go
"api.MyBinding": {
"type":"object",
"properties":{
"crt":{
"type":"string",
"format":"base64",
"example":"U3dhZ2dlciByb2Nrcw=="
},
"key":{
"type":"string",
"format":"base64",
"example":"U3dhZ2dlciByb2Nrcw=="
}
}
}
```
### Add extension info to struct field
```go
@ -627,4 +677,4 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
## License
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fswaggo%2Fswag.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fswaggo%2Fswag?ref=badge_large)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fswaggo%2Fswag.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fswaggo%2Fswag?ref=badge_large)

View File

@ -1,15 +1,23 @@
package main
import (
"fmt"
"log"
"os"
"github.com/pkg/errors"
"github.com/swaggo/swag"
"github.com/swaggo/swag/gen"
"github.com/urfave/cli"
)
const searchDirFlag = "dir"
const generalInfoFlag = "generalInfo"
const propertyStrategyFlag = "propertyStrategy"
const outputFlag = "output"
const parseVendorFlag = "parseVendor"
const parseDependency = "parseDependency"
const markdownFilesDirFlag = "markdownFiles"
func main() {
app := cli.NewApp()
app.Version = swag.Version
@ -20,16 +28,18 @@ func main() {
Aliases: []string{"i"},
Usage: "Create docs.go",
Action: func(c *cli.Context) error {
searchDir := c.String("dir")
mainAPIFile := c.String("generalInfo")
strategy := c.String("propertyStrategy")
outputDir := c.String("output")
parseVendor := c.Bool("parseVendor")
searchDir := c.String(searchDirFlag)
mainAPIFile := c.String(generalInfoFlag)
strategy := c.String(propertyStrategyFlag)
outputDir := c.String(outputFlag)
parseVendor := c.Bool(parseVendorFlag)
parseDependency := c.Bool(parseDependency)
markdownFilesDir := c.String(markdownFilesDirFlag)
switch strategy {
case swag.CamelCase, swag.SnakeCase, swag.PascalCase:
default:
return errors.Errorf("not supported %s propertyStrategy", strategy)
return fmt.Errorf("not supported %s propertyStrategy", strategy)
}
return gen.New().Build(&gen.Config{
@ -38,6 +48,8 @@ func main() {
PropNamingStrategy: strategy,
OutputDir: outputDir,
ParseVendor: parseVendor,
ParseDependency: parseDependency,
MarkdownFilesDir: markdownFilesDir,
})
},
Flags: []cli.Flag{
@ -65,6 +77,15 @@ func main() {
Name: "parseVendor",
Usage: "Parse go files in 'vendor' folder, disabled by default",
},
cli.BoolFlag{
Name: "parseDependency",
Usage: "Parse go files in outside dependency folder, disabled by default",
},
cli.StringFlag{
Name: "markdownFiles, md",
Value: "",
Usage: "Parse folder containing markdown files to use as description, disabled by default",
},
},
},
}

View File

@ -15,14 +15,14 @@ func isRelease() bool {
return swagMode == release
}
//Println calls Output to print to the standard logger when release mode.
// Println calls Output to print to the standard logger when release mode.
func Println(v ...interface{}) {
if isRelease() {
log.Println(v...)
}
}
//Printf calls Output to print to the standard logger when release mode.
// Printf calls Output to print to the standard logger when release mode.
func Printf(format string, v ...interface{}) {
if isRelease() {
log.Printf(format, v...)

View File

@ -1,22 +1,26 @@
package gen
import (
"bytes"
"encoding/json"
"fmt"
"go/format"
"io"
"log"
"os"
"path"
"strings"
"text/template"
"time"
"github.com/go-openapi/spec"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
"github.com/swaggo/swag"
)
// Gen presents a generate tool for swag.
type Gen struct {
}
type Gen struct{}
// New creates a new Gen.
func New() *Gen {
@ -28,41 +32,51 @@ type Config struct {
// SearchDir the swag would be parse
SearchDir string
//OutputDir represents the output directory for al the generated files
// OutputDir represents the output directory for al the generated files
OutputDir string
//MainAPIFile the Go file path in which 'swagger general API Info' is written
// MainAPIFile the Go file path in which 'swagger general API Info' is written
MainAPIFile string
//PropNamingStrategy represents property naming strategy like snakecase,camelcase,pascalcase
// PropNamingStrategy represents property naming strategy like snakecase,camelcase,pascalcase
PropNamingStrategy string
//ParseVendor whether swag should be parse vendor folder
// ParseVendor whether swag should be parse vendor folder
ParseVendor bool
// ParseDependencies whether swag should be parse outside dependency folder
ParseDependency bool
// MarkdownFilesDir used to find markdownfiles, which can be used for tag descriptions
MarkdownFilesDir string
}
// Build builds swagger json file for gived searchDir and mainAPIFile. Returns json
// Build builds swagger json file for given searchDir and mainAPIFile. Returns json
func (g *Gen) Build(config *Config) error {
if _, err := os.Stat(config.SearchDir); os.IsNotExist(err) {
return fmt.Errorf("dir: %s is not exist", config.SearchDir)
}
log.Println("Generate swagger docs....")
p := swag.New()
p := swag.New(swag.SetMarkdownFileDirectory(config.MarkdownFilesDir))
p.PropNamingStrategy = config.PropNamingStrategy
p.ParseVendor = config.ParseVendor
p.ParseDependency = config.ParseDependency
if err := p.ParseAPI(config.SearchDir, config.MainAPIFile); err != nil {
return err
}
swagger := p.GetSwagger()
b, err := json.MarshalIndent(swagger, "", " ")
b, err := g.jsonIndent(swagger)
if err != nil {
return err
}
os.MkdirAll(config.OutputDir, os.ModePerm)
if err := os.MkdirAll(config.OutputDir, os.ModePerm); err != nil {
return err
}
docs, err := os.Create(path.Join(config.OutputDir, "docs.go"))
if err != nil {
return err
@ -73,9 +87,11 @@ func (g *Gen) Build(config *Config) error {
if err != nil {
return err
}
defer swaggerJSON.Close()
swaggerJSON.Write(b)
if _, err := swaggerJSON.Write(b); err != nil {
return err
}
swaggerYAML, err := os.Create(path.Join(config.OutputDir, "swagger.yaml"))
if err != nil {
@ -85,18 +101,16 @@ func (g *Gen) Build(config *Config) error {
defer swaggerYAML.Close()
y, err := yaml.JSONToYAML(b)
if err != nil {
return errors.Wrap(err, "cannot covert json to yaml")
return fmt.Errorf("cannot covert json to yaml error: %s", err)
}
swaggerYAML.Write(y)
if _, err := swaggerYAML.Write(y); err != nil {
return err
}
if err := packageTemplate.Execute(docs, struct {
Timestamp time.Time
Doc string
}{
Timestamp: time.Now(),
Doc: "`" + string(b) + "`",
}); err != nil {
// Write doc
err = g.writeGoDoc(docs, swagger)
if err != nil {
return err
}
@ -107,7 +121,102 @@ func (g *Gen) Build(config *Config) error {
return nil
}
var packageTemplate = template.Must(template.New("").Parse(`// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
func (g *Gen) jsonIndent(data interface{}) ([]byte, error) {
return json.MarshalIndent(data, "", " ")
}
func (g *Gen) formatSource(src []byte) []byte {
code, err := format.Source(src)
if err != nil {
code = src // Output the unformated code anyway
}
return code
}
func (g *Gen) writeGoDoc(output io.Writer, swagger *spec.Swagger) error {
generator, err := template.New("swagger_info").Funcs(template.FuncMap{
"printDoc": func(v string) string {
// Add schemes
v = "{\n \"schemes\": {{ marshal .Schemes }}," + v[1:]
// Sanitize backticks
return strings.Replace(v, "`", "`+\"`\"+`", -1)
},
}).Parse(packageTemplate)
if err != nil {
return err
}
swaggerSpec := &spec.Swagger{
VendorExtensible: swagger.VendorExtensible,
SwaggerProps: spec.SwaggerProps{
ID: swagger.ID,
Consumes: swagger.Consumes,
Produces: swagger.Produces,
Swagger: swagger.Swagger,
Info: &spec.Info{
VendorExtensible: swagger.Info.VendorExtensible,
InfoProps: spec.InfoProps{
Description: "{{.Description}}",
Title: "{{.Title}}",
TermsOfService: swagger.Info.TermsOfService,
Contact: swagger.Info.Contact,
License: swagger.Info.License,
Version: "{{.Version}}",
},
},
Host: "{{.Host}}",
BasePath: "{{.BasePath}}",
Paths: swagger.Paths,
Definitions: swagger.Definitions,
Parameters: swagger.Parameters,
Responses: swagger.Responses,
SecurityDefinitions: swagger.SecurityDefinitions,
Security: swagger.Security,
Tags: swagger.Tags,
ExternalDocs: swagger.ExternalDocs,
},
}
// crafted docs.json
buf, err := g.jsonIndent(swaggerSpec)
if err != nil {
return err
}
buffer := &bytes.Buffer{}
err = generator.Execute(buffer, struct {
Timestamp time.Time
Doc string
Host string
BasePath string
Schemes []string
Title string
Description string
Version string
}{
Timestamp: time.Now(),
Doc: string(buf),
Host: swagger.Host,
BasePath: swagger.BasePath,
Schemes: swagger.Schemes,
Title: swagger.Info.Title,
Description: swagger.Info.Description,
Version: swagger.Info.Version,
})
if err != nil {
return err
}
code := g.formatSource(buffer.Bytes())
// write
_, err = output.Write(code)
return err
}
var packageTemplate = `// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
// This file was generated by swaggo/swag at
// {{ .Timestamp }}
@ -115,34 +224,52 @@ package docs
import (
"bytes"
"encoding/json"
"strings"
"github.com/alecthomas/template"
"github.com/swaggo/swag"
)
var doc = {{.Doc}}
var doc = ` + "`{{ printDoc .Doc}}`" + `
type swaggerInfo struct {
Version string
Host string
BasePath string
Schemes []string
Title string
Description string
}
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo swaggerInfo
var SwaggerInfo = swaggerInfo{
Version: {{ printf "%q" .Version}},
Host: {{ printf "%q" .Host}},
BasePath: {{ printf "%q" .BasePath}},
Schemes: []string{ {{ range $index, $schema := .Schemes}}{{if gt $index 0}},{{end}}{{printf "%q" $schema}}{{end}} },
Title: {{ printf "%q" .Title}},
Description: {{ printf "%q" .Description}},
}
type s struct{}
func (s *s) ReadDoc() string {
t, err := template.New("swagger_info").Parse(doc)
sInfo := SwaggerInfo
sInfo.Description = strings.Replace(sInfo.Description, "\n", "\\n", -1)
t, err := template.New("swagger_info").Funcs(template.FuncMap{
"marshal": func(v interface{}) string {
a, _ := json.Marshal(v)
return string(a)
},
}).Parse(doc)
if err != nil {
return doc
}
var tpl bytes.Buffer
if err := t.Execute(&tpl, SwaggerInfo); err != nil {
if err := t.Execute(&tpl, sInfo); err != nil {
return doc
}
@ -152,4 +279,4 @@ func (s *s) ReadDoc() string {
func init() {
swag.Register(swag.Name, &s{})
}
`))
`

31
vendor/github.com/swaggo/swag/go.mod generated vendored
View File

@ -1,31 +1,14 @@
module github.com/swaggo/swag
require (
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/KyleBanks/depth v1.2.1
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
github.com/ghodss/yaml v1.0.0
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 // indirect
github.com/gin-gonic/gin v1.3.0
github.com/go-openapi/jsonpointer v0.18.0 // indirect
github.com/go-openapi/jsonreference v0.18.0
github.com/go-openapi/spec v0.18.0
github.com/go-openapi/swag v0.18.0 // indirect
github.com/golang/protobuf v1.3.1 // indirect
github.com/json-iterator/go v1.1.6 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe // indirect
github.com/mattn/go-isatty v0.0.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/pkg/errors v0.8.1
github.com/satori/go.uuid v1.2.0
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 // indirect
github.com/go-openapi/jsonreference v0.19.0
github.com/go-openapi/spec v0.19.0
github.com/stretchr/testify v1.3.0
github.com/swaggo/gin-swagger v1.1.0
github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780 // indirect
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14
github.com/swaggo/gin-swagger v1.2.0
github.com/urfave/cli v1.20.0
golang.org/x/net v0.0.0-20190322120337-addf6b3196f6 // indirect
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc // indirect
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b
)

89
vendor/github.com/swaggo/swag/go.sum generated vendored
View File

@ -1,106 +1,85 @@
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/PuerkitoBio/purell v1.1.0 h1:rmGxhojJlM0tuKtfdvliR84CFHljx9ag64t2xmVkjK4=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 h1:AzN37oI0cOS+cougNAV9szl6CVoj2RYwzS3DpUQNtlY=
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/go-openapi/jsonpointer v0.17.0 h1:nH6xp8XdXHx8dqveo0ZuJBluCO2qGrPbDNZ0dwoRHP0=
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.18.0 h1:KVRzjXpMzgdM4GEMDmDTnGcY5yBwGWreJwmmk4k35yU=
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.18.0 h1:oP2OUNdG1l2r5kYhrfVMXO54gWmzcfAwP/GFuHpNTkE=
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/spec v0.18.0 h1:aIjeyG5mo5/FrvDkpKKEGZPmF9MPHahS72mzfVqeQXQ=
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/jsonreference v0.19.0 h1:BqWKpV1dFd+AuiKlgtddwVIFQsuMpxfBDBHGfM2yNpk=
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k4=
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/swag v0.17.0 h1:iqrgMg7Q7SvtbWLlltPrkMs0UBJI6oTSs79JFRUi880=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.18.0 h1:1DU8Km1MRGv9Pj7BNLmkA+umwTStwDHttXvx3NhJA70=
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329 h1:2gxZ0XQIU/5z3Z3bUBu+FXuk2pFbkN6tcwi/pjyaDic=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe h1:W/GaMY0y69G4cFlmsC6B9sbuo2fP8OFP1ABjt4kPz+w=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/swaggo/gin-swagger v1.1.0 h1:ZI6/82S07DkkrMfGKbJhKj1R+QNTICkeAJP06pU36pU=
github.com/swaggo/gin-swagger v1.1.0/go.mod h1:FQlm07YuT1glfN3hQiO11UQ2m39vOCZ/aa3WWr5E+XU=
github.com/swaggo/swag v1.4.0/go.mod h1:hog2WgeMOrQ/LvQ+o1YGTeT+vWVrbi0SiIslBtxKTyM=
github.com/ugorji/go v1.1.2 h1:JON3E2/GPW2iDNGoSAusl1KDf5TRQ8k8q7Tp097pZGs=
github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2 h1:EICbibRW4JNKMcY+LsWmuwob+CRS1BmdRdjphAm9mH4=
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780 h1:vG/gY/PxA3v3l04qxe3tDjXyu3bozii8ulSlIPOYKhI=
github.com/ugorji/go/codec v0.0.0-20190320090025-2dc34c0b8780/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA=
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI=
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190322120337-addf6b3196f6 h1:78jEq2G3J16aXneH23HSnTQQTCwMHoyO8VEiUH+bpPM=
golang.org/x/net v0.0.0-20190322120337-addf6b3196f6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a h1:+KkCgOMgnKSgenxTBoiwkMqTiouMIy/3o8RLdmSbGoY=
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc h1:4gbWbmmPFp4ySWICouJl6emP0MyS31yy9SrTlAGFT+g=
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190110015856-aa033095749b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89 h1:iWXXYN3edZ3Nd/7I6Rt1sXrWVmhF9bgVtlEJ7BbH124=
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b h1:/mJ+GKieZA6hFDQGdWZrjj4AXPl5ylY+5HusG80roy0=
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -1,6 +1,7 @@
package swag
import (
"encoding/json"
"fmt"
"go/ast"
goparser "go/parser"
@ -13,7 +14,6 @@ import (
"github.com/go-openapi/jsonreference"
"github.com/go-openapi/spec"
"github.com/pkg/errors"
"golang.org/x/tools/go/loader"
)
@ -61,16 +61,14 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro
if len(commentLine) == 0 {
return nil
}
attribute := strings.Fields(commentLine)[0]
lineRemainder := strings.TrimSpace(commentLine[len(attribute):])
switch strings.ToLower(attribute) {
lowerAttribute := strings.ToLower(attribute)
var err error
switch lowerAttribute {
case "@description":
if operation.Description == "" {
operation.Description = lineRemainder
} else {
operation.Description += "\n" + lineRemainder
}
operation.ParseDescriptionComment(lineRemainder)
case "@summary":
operation.Summary = lineRemainder
case "@id":
@ -78,37 +76,50 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro
case "@tags":
operation.ParseTagsComment(lineRemainder)
case "@accept":
if err := operation.ParseAcceptComment(lineRemainder); err != nil {
return err
}
err = operation.ParseAcceptComment(lineRemainder)
case "@produce":
if err := operation.ParseProduceComment(lineRemainder); err != nil {
return err
}
err = operation.ParseProduceComment(lineRemainder)
case "@param":
if err := operation.ParseParamComment(lineRemainder, astFile); err != nil {
return err
}
err = operation.ParseParamComment(lineRemainder, astFile)
case "@success", "@failure":
if err := operation.ParseResponseComment(lineRemainder, astFile); err != nil {
if err := operation.ParseEmptyResponseComment(lineRemainder); err != nil {
if err := operation.ParseEmptyResponseOnly(lineRemainder); err != nil {
return err
}
}
}
err = operation.ParseResponseComment(lineRemainder, astFile)
case "@header":
if err := operation.ParseResponseHeaderComment(lineRemainder, astFile); err != nil {
return err
}
err = operation.ParseResponseHeaderComment(lineRemainder, astFile)
case "@router":
if err := operation.ParseRouterComment(lineRemainder); err != nil {
return err
}
err = operation.ParseRouterComment(lineRemainder)
case "@security":
if err := operation.ParseSecurityComment(lineRemainder); err != nil {
return err
err = operation.ParseSecurityComment(lineRemainder)
case "@deprecated":
operation.Deprecate()
default:
err = operation.ParseMetadata(attribute, lowerAttribute, lineRemainder)
}
return err
}
// ParseDescriptionComment godoc
func (operation *Operation) ParseDescriptionComment(lineRemainder string) {
if operation.Description == "" {
operation.Description = lineRemainder
return
}
operation.Description += "\n" + lineRemainder
}
// ParseMetadata godoc
func (operation *Operation) ParseMetadata(attribute, lowerAttribute, lineRemainder string) error {
// parsing specific meta data extensions
if strings.HasPrefix(lowerAttribute, "@x-") {
if len(lineRemainder) == 0 {
return fmt.Errorf("annotation %s need a value", attribute)
}
var valueJSON interface{}
if err := json.Unmarshal([]byte(lineRemainder), &valueJSON); err != nil {
return fmt.Errorf("annotation %s need a valid json value", attribute)
}
operation.Operation.AddExtension(attribute[1:], valueJSON) // Trim "@" at head
}
return nil
}
@ -116,7 +127,7 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro
var paramPattern = regexp.MustCompile(`(\S+)[\s]+([\w]+)[\s]+([\S.]+)[\s]+([\w]+)[\s]+"([^"]+)"`)
// ParseParamComment parses params return []string of param properties
// E.g. @Param queryText form string true "The email for login"
// E.g. @Param queryText formData string true "The email for login"
// [param name] [paramType] [data type] [is mandatory?] [Comment]
// E.g. @Param some_id path int true "Some ID"
func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.File) error {
@ -126,34 +137,78 @@ func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.F
}
name := matches[1]
paramType := matches[2]
refType := TransToValidSchemeType(matches[3])
schemaType := matches[3]
// Detect refType
objectType := "object"
if strings.HasPrefix(refType, "[]") == true {
objectType = "array"
refType = strings.TrimPrefix(refType, "[]")
} else if IsPrimitiveType(refType) ||
paramType == "formData" && refType == "file" {
objectType = "primitive"
}
requiredText := strings.ToLower(matches[4])
required := requiredText == "true" || requiredText == "required"
description := matches[5]
var param spec.Parameter
param := createParameter(paramType, description, name, refType, required)
//five possible parameter types.
switch paramType {
case "query", "path", "header":
param = createParameter(paramType, description, name, TransToValidSchemeType(schemaType), required)
case "path", "header", "formData":
switch objectType {
case "array", "object":
return fmt.Errorf("%s is not supported type for %s", refType, paramType)
}
case "query":
switch objectType {
case "array":
if !IsPrimitiveType(refType) {
return fmt.Errorf("%s is not supported array type for %s", refType, paramType)
}
param.SimpleSchema.Type = "array"
param.SimpleSchema.Items = &spec.Items{
SimpleSchema: spec.SimpleSchema{
Type: refType,
},
}
case "object":
return fmt.Errorf("%s is not supported type for %s", refType, paramType)
}
case "body":
param = createParameter(paramType, description, name, "object", required) // TODO: if Parameter types can be objects, but also primitives and arrays
if err := operation.registerSchemaType(schemaType, astFile); err != nil {
return err
switch objectType {
case "primitive":
param.Schema.Type = spec.StringOrArray{refType}
case "array":
param.Schema.Items = &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{},
},
}
// Arrau of Primitive or Object
if IsPrimitiveType(refType) {
param.Schema.Items.Schema.Type = spec.StringOrArray{refType}
} else {
if err := operation.registerSchemaType(refType, astFile); err != nil {
return err
}
param.Schema.Items.Schema.Ref = spec.Ref{Ref: jsonreference.MustCreateRef("#/definitions/" + refType)}
}
case "object":
if err := operation.registerSchemaType(refType, astFile); err != nil {
return err
}
param.Schema.Type = spec.StringOrArray{objectType}
param.Schema.Ref = spec.Ref{
Ref: jsonreference.MustCreateRef("#/definitions/" + refType),
}
}
param.Schema.Ref = spec.Ref{
Ref: jsonreference.MustCreateRef("#/definitions/" + schemaType),
}
case "formData":
param = createParameter(paramType, description, name, TransToValidSchemeType(schemaType), required)
default:
return fmt.Errorf("%s is not supported paramType", paramType)
}
if err := operation.parseAndExtractionParamAttribute(commentLine, schemaType, &param); err != nil {
if err := operation.parseAndExtractionParamAttribute(commentLine, refType, &param); err != nil {
return err
}
operation.Operation.Parameters = append(operation.Operation.Parameters, param)
@ -184,7 +239,7 @@ func (operation *Operation) registerSchemaType(schemaType string, astFile *ast.F
var err error
typeSpec, err = findTypeDef(impPath, typeName)
if err != nil {
return errors.Wrapf(err, "can not find type def: %q", schemaType)
return fmt.Errorf("can not find type def: %q error: %s", schemaType, err)
}
break
}
@ -223,81 +278,50 @@ var regexAttributes = map[string]*regexp.Regexp{
func (operation *Operation) parseAndExtractionParamAttribute(commentLine, schemaType string, param *spec.Parameter) error {
schemaType = TransToValidSchemeType(schemaType)
for attrKey, re := range regexAttributes {
attr, err := findAttr(re, commentLine)
if err != nil {
continue
}
switch attrKey {
case "enums":
enums, err := findAttrList(re, commentLine)
err := setEnumParam(attr, schemaType, param)
if err != nil {
break
}
for _, e := range enums {
e = strings.TrimSpace(e)
param.Enum = append(param.Enum, defineType(schemaType, e))
return err
}
case "maxinum":
attr, err := findAttr(re, commentLine)
n, err := setNumberParam(attrKey, schemaType, attr, commentLine)
if err != nil {
break
}
if schemaType != "integer" && schemaType != "number" {
return fmt.Errorf("maxinum is attribute to set to a number. comment=%s got=%s", commentLine, schemaType)
}
n, err := strconv.ParseFloat(attr, 64)
if err != nil {
return fmt.Errorf("maximum is allow only a number. comment=%s got=%s", commentLine, attr)
return err
}
param.Maximum = &n
case "mininum":
attr, err := findAttr(re, commentLine)
n, err := setNumberParam(attrKey, schemaType, attr, commentLine)
if err != nil {
break
}
if schemaType != "integer" && schemaType != "number" {
return fmt.Errorf("mininum is attribute to set to a number. comment=%s got=%s", commentLine, schemaType)
}
n, err := strconv.ParseFloat(attr, 64)
if err != nil {
return fmt.Errorf("mininum is allow only a number got=%s", attr)
return err
}
param.Minimum = &n
case "default":
attr, err := findAttr(re, commentLine)
value, err := defineType(schemaType, attr)
if err != nil {
break
return nil
}
param.Default = defineType(schemaType, attr)
param.Default = value
case "maxlength":
attr, err := findAttr(re, commentLine)
n, err := setStringParam(attrKey, schemaType, attr, commentLine)
if err != nil {
break
}
if schemaType != "string" {
return fmt.Errorf("maxlength is attribute to set to a number. comment=%s got=%s", commentLine, schemaType)
}
n, err := strconv.ParseInt(attr, 10, 64)
if err != nil {
return fmt.Errorf("maxlength is allow only a number got=%s", attr)
return err
}
param.MaxLength = &n
case "minlength":
attr, err := findAttr(re, commentLine)
n, err := setStringParam(attrKey, schemaType, attr, commentLine)
if err != nil {
break
}
if schemaType != "string" {
return fmt.Errorf("maxlength is attribute to set to a number. comment=%s got=%s", commentLine, schemaType)
}
n, err := strconv.ParseInt(attr, 10, 64)
if err != nil {
return fmt.Errorf("minlength is allow only a number got=%s", attr)
return err
}
param.MinLength = &n
case "format":
attr, err := findAttr(re, commentLine)
if err != nil {
break
}
param.Format = attr
}
}
return nil
}
@ -312,40 +336,67 @@ func findAttr(re *regexp.Regexp, commentLine string) (string, error) {
return strings.TrimSpace(attr[l+1 : r]), nil
}
func findAttrList(re *regexp.Regexp, commentLine string) ([]string, error) {
attr, err := findAttr(re, commentLine)
if err != nil {
return []string{""}, err
func setStringParam(name, schemaType, attr, commentLine string) (int64, error) {
if schemaType != "string" {
return 0, fmt.Errorf("%s is attribute to set to a number. comment=%s got=%s", name, commentLine, schemaType)
}
return strings.Split(attr, ","), nil
n, err := strconv.ParseInt(attr, 10, 64)
if err != nil {
return 0, fmt.Errorf("%s is allow only a number got=%s", name, attr)
}
return n, nil
}
func setNumberParam(name, schemaType, attr, commentLine string) (float64, error) {
if schemaType != "integer" && schemaType != "number" {
return 0, fmt.Errorf("%s is attribute to set to a number. comment=%s got=%s", name, commentLine, schemaType)
}
n, err := strconv.ParseFloat(attr, 64)
if err != nil {
return 0, fmt.Errorf("maximum is allow only a number. comment=%s got=%s", commentLine, attr)
}
return n, nil
}
func setEnumParam(attr, schemaType string, param *spec.Parameter) error {
for _, e := range strings.Split(attr, ",") {
e = strings.TrimSpace(e)
value, err := defineType(schemaType, e)
if err != nil {
return err
}
param.Enum = append(param.Enum, value)
}
return nil
}
// defineType enum value define the type (object and array unsupported)
func defineType(schemaType string, value string) interface{} {
func defineType(schemaType string, value string) (interface{}, error) {
schemaType = TransToValidSchemeType(schemaType)
switch schemaType {
case "string":
return value
return value, nil
case "number":
v, err := strconv.ParseFloat(value, 64)
if err != nil {
panic(fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err))
return nil, fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err)
}
return v
return v, nil
case "integer":
v, err := strconv.Atoi(value)
if err != nil {
panic(fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err))
return nil, fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err)
}
return v
return v, nil
case "boolean":
v, err := strconv.ParseBool(value)
if err != nil {
panic(fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err))
return nil, fmt.Errorf("enum value %s can't convert to %s err: %s", value, schemaType, err)
}
return v
return v, nil
default:
panic(fmt.Errorf("%s is unsupported type in enum value", schemaType))
return nil, fmt.Errorf("%s is unsupported type in enum value", schemaType)
}
}
@ -464,7 +515,7 @@ func findTypeDef(importPath, typeName string) (*ast.TypeSpec, error) {
pkgInfo := lprog.Package(importPath)
if pkgInfo == nil {
return nil, errors.New("package was nil")
return nil, fmt.Errorf("package was nil")
}
// TODO: possibly cache pkgInfo since it's an expensive operation
@ -482,17 +533,21 @@ func findTypeDef(importPath, typeName string) (*ast.TypeSpec, error) {
}
}
}
return nil, errors.New("type spec not found")
return nil, fmt.Errorf("type spec not found")
}
var responsePattern = regexp.MustCompile(`([\d]+)[\s]+([\w\{\}]+)[\s]+([\w\-\.\/]+)[^"]*(.*)?`)
// ParseResponseComment parses comment for gived `response` comment string.
// ParseResponseComment parses comment for given `response` comment string.
func (operation *Operation) ParseResponseComment(commentLine string, astFile *ast.File) error {
var matches []string
if matches = responsePattern.FindStringSubmatch(commentLine); len(matches) != 5 {
return fmt.Errorf("can not parse response comment \"%s\"", commentLine)
err := operation.ParseEmptyResponseComment(commentLine)
if err != nil {
return operation.ParseEmptyResponseOnly(commentLine)
}
return err
}
response := spec.Response{}
@ -508,6 +563,11 @@ func (operation *Operation) ParseResponseComment(commentLine string, astFile *as
schemaType := strings.Trim(matches[2], "{}")
refType := matches[3]
if !IsGolangPrimitiveType(refType) && !strings.Contains(refType, ".") {
currentPkgName := astFile.Name.String()
refType = currentPkgName + "." + refType
}
if operation.parser != nil { // checking refType has existing in 'TypeDefinitions'
if err := operation.registerSchemaType(refType, astFile); err != nil {
return err
@ -515,10 +575,10 @@ func (operation *Operation) ParseResponseComment(commentLine string, astFile *as
}
// so we have to know all type in app
//TODO: we might omitted schema.type if schemaType equals 'object'
response.Schema = &spec.Schema{SchemaProps: spec.SchemaProps{Type: []string{schemaType}}}
if schemaType == "object" {
response.Schema.SchemaProps = spec.SchemaProps{}
response.Schema.Ref = spec.Ref{
Ref: jsonreference.MustCreateRef("#/definitions/" + refType),
}

File diff suppressed because it is too large Load Diff

View File

@ -52,6 +52,11 @@ func parseFieldSelectorExpr(astTypeSelectorExpr *ast.SelectorExpr, parser *Parse
if pkgName, ok := astTypeSelectorExpr.X.(*ast.Ident); ok {
if typeDefinitions, ok := parser.TypeDefinitions[pkgName.Name][astTypeSelectorExpr.Sel.Name]; ok {
if expr, ok := typeDefinitions.Type.(*ast.SelectorExpr); ok {
if primitiveType, err := convertFromSpecificToPrimitive(expr.Sel.Name); err == nil {
return propertyNewFunc(primitiveType, "")
}
}
parser.ParseDefinition(pkgName.Name, astTypeSelectorExpr.Sel.Name, typeDefinitions)
return propertyNewFunc(astTypeSelectorExpr.Sel.Name, pkgName.Name)
}
@ -59,28 +64,26 @@ func parseFieldSelectorExpr(astTypeSelectorExpr *ast.SelectorExpr, parser *Parse
return propertyName{SchemaType: actualPrimitiveType, ArrayType: actualPrimitiveType}
}
}
Printf("%s is not supported. but it will be set with string temporary. Please report any problems.\n", astTypeSelectorExpr.Sel.Name)
return propertyName{SchemaType: "string", ArrayType: "string"}
}
// getPropertyName returns the string value for the given field if it exists, otherwise it panics.
// getPropertyName returns the string value for the given field if it exists
// allowedValues: array, boolean, integer, null, number, object, string
func getPropertyName(expr ast.Expr, parser *Parser) propertyName {
func getPropertyName(expr ast.Expr, parser *Parser) (propertyName, error) {
if astTypeSelectorExpr, ok := expr.(*ast.SelectorExpr); ok {
return parseFieldSelectorExpr(astTypeSelectorExpr, parser, newProperty)
return parseFieldSelectorExpr(astTypeSelectorExpr, parser, newProperty), nil
}
// check if it is a custom type
typeName := fmt.Sprintf("%v", expr)
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[typeName]; isCustomType {
return propertyName{SchemaType: actualPrimitiveType, ArrayType: actualPrimitiveType}
return propertyName{SchemaType: actualPrimitiveType, ArrayType: actualPrimitiveType}, nil
}
if astTypeIdent, ok := expr.(*ast.Ident); ok {
name := astTypeIdent.Name
schemeType := TransToValidSchemeType(name)
return propertyName{SchemaType: schemeType, ArrayType: schemeType}
return propertyName{SchemaType: schemeType, ArrayType: schemeType}, nil
}
if ptr, ok := expr.(*ast.StarExpr); ok {
@ -88,23 +91,24 @@ func getPropertyName(expr ast.Expr, parser *Parser) propertyName {
}
if astTypeArray, ok := expr.(*ast.ArrayType); ok { // if array
return getArrayPropertyName(astTypeArray, parser)
if _, ok := astTypeArray.Elt.(*ast.StructType); ok {
return propertyName{SchemaType: "array", ArrayType: "object"}, nil
}
return getArrayPropertyName(astTypeArray, parser), nil
}
if _, ok := expr.(*ast.MapType); ok { // if map
//TODO: support map
return propertyName{SchemaType: "object", ArrayType: "object"}
return propertyName{SchemaType: "object", ArrayType: "object"}, nil
}
if _, ok := expr.(*ast.StructType); ok { // if struct
return propertyName{SchemaType: "object", ArrayType: "object"}
return propertyName{SchemaType: "object", ArrayType: "object"}, nil
}
if _, ok := expr.(*ast.InterfaceType); ok { // if interface{}
return propertyName{SchemaType: "object", ArrayType: "object"}
return propertyName{SchemaType: "object", ArrayType: "object"}, nil
}
panic("not supported" + fmt.Sprint(expr))
return propertyName{}, errors.New("not supported" + fmt.Sprint(expr))
}
func getArrayPropertyName(astTypeArray *ast.ArrayType, parser *Parser) propertyName {

View File

@ -2,11 +2,12 @@ package swag
import "fmt"
// CheckSchemaType begins panicking if typeName is not a name of primitive type
func CheckSchemaType(typeName string) {
// CheckSchemaType checks if typeName is not a name of primitive type
func CheckSchemaType(typeName string) error {
if !IsPrimitiveType(typeName) {
panic(fmt.Errorf("%s is not basic types", typeName))
return fmt.Errorf("%s is not basic types", typeName)
}
return nil
}
// IsPrimitiveType determine whether the type name is a primitive type

View File

@ -1,4 +1,4 @@
package swag
// Version of swag
const Version = "v1.5.0"
const Version = "v1.6.3"