Swaggo update and fixes

This commit is contained in:
kolaente 2020-04-12 21:45:17 +02:00
parent d28f005552
commit 616ed4ad89
Signed by untrusted user: konrad
GPG Key ID: F40E70337AB24C9B
55 changed files with 839 additions and 508 deletions

View File

@ -192,7 +192,7 @@ do-the-swag:
@hash swag > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
go install $(GOFLAGS) github.com/swaggo/swag/cmd/swag; \
fi
swag init -g pkg/routes/routes.go -o ./pkg/swagger;
swag init --parseVendor -g pkg/routes/routes.go -o ./pkg/swagger;
# Fix the generated swagger file, currently a workaround until swaggo can properly use go mod
sed -i '/"definitions": {/a "code.vikunja.io.web.HTTPError": {"type": "object","properties": {"code": {"type": "integer"},"message": {"type": "string"}}},' pkg/swagger/docs.go;
sed -i 's/code.vikunja.io\/web.HTTPError/code.vikunja.io.web.HTTPError/g' pkg/swagger/docs.go;

10
go.mod
View File

@ -33,8 +33,8 @@ require (
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
github.com/garyburd/redigo v1.6.0 // indirect
github.com/go-openapi/jsonreference v0.19.3 // indirect
github.com/go-openapi/spec v0.19.4 // indirect
github.com/go-openapi/spec v0.19.7 // indirect
github.com/go-openapi/swag v0.19.8 // indirect
github.com/go-redis/redis/v7 v7.2.0
github.com/go-sql-driver/mysql v1.5.0
github.com/go-testfixtures/testfixtures/v3 v3.1.1
@ -50,7 +50,7 @@ require (
github.com/labstack/gommon v0.3.0
github.com/laurent22/ical-go v0.1.1-0.20181107184520-7e5d6ade8eef
github.com/lib/pq v1.3.0
github.com/mailru/easyjson v0.7.0 // indirect
github.com/mailru/easyjson v0.7.1 // indirect
github.com/mattn/go-sqlite3 v2.0.3+incompatible
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
@ -68,9 +68,9 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.6.3
github.com/stretchr/testify v1.5.1
github.com/swaggo/swag v1.6.3
github.com/swaggo/swag v1.6.5
github.com/ulule/limiter/v3 v3.5.0
github.com/urfave/cli v1.22.2 // indirect
github.com/urfave/cli/v2 v2.1.1 // indirect
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect

12
go.sum
View File

@ -114,10 +114,14 @@ github.com/go-openapi/spec v0.19.0 h1:A4SZ6IWh3lnjH0rG0Z5lkxazMGBECtrZcbyYQi+64k
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo=
github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/spec v0.19.7 h1:0xWSeMd35y5avQAThZR2PkEuqSosoS5t6gDH4L8n11M=
github.com/go-openapi/spec v0.19.7/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.8 h1:vfK6jLhs7OI4tAXkvkooviaE1JEPcw3mutyegLHHjmk=
github.com/go-openapi/swag v0.19.8/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
@ -247,6 +251,8 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8=
github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
@ -342,6 +348,7 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
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/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
@ -394,6 +401,10 @@ github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
github.com/swaggo/swag v1.6.3 h1:N+uVPGP4H2hXoss2pt5dctoSUPKKRInr6qcTMOm0usI=
github.com/swaggo/swag v1.6.3/go.mod h1:wcc83tB4Mb2aNiL/HP4MFeQdpHUrca+Rp/DRNgWAUio=
github.com/swaggo/swag v1.6.5 h1:2C+t+xyK6p1sujqncYO/VnMvPZcBJjNdKKyxbOdAW8o=
github.com/swaggo/swag v1.6.5/go.mod h1:Y7ZLSS0d0DdxhWGVhQdu+Bu1QhaF5k0RD7FKdiAykeY=
github.com/swaggo/swag v1.6.6-0.20200404095705-3b82b47aece6 h1:OUQztxMfijnku6tqmhbfe7+ERhDwaPhp47HW9qT3QC4=
github.com/swaggo/swag v1.6.6-0.20200404095705-3b82b47aece6/go.mod h1:xDhTyuFIujYiN3DKWC/H/83xcfHp+UE/IzWWampG7Zc=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@ -409,6 +420,7 @@ 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=
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=

View File

@ -73,8 +73,8 @@ func (bt *BulkTask) CanUpdate(a web.Auth) (bool, error) {
// @Security JWTKeyAuth
// @Param task body models.BulkTask true "The task object. Looks like a normal task, the only difference is it uses an array of list_ids to update."
// @Success 200 {object} models.Task "The updated task object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid task object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the task (aka its list)"
// @Failure 400 {object} web.HTTPError "Invalid task object provided."
// @Failure 403 {object} web.HTTPError "The user does not have access to the task (aka its list)"
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/bulk [post]
func (bt *BulkTask) Update() (err error) {

View File

@ -60,7 +60,7 @@ func (Label) TableName() string {
// @Security JWTKeyAuth
// @Param label body models.Label true "The label object"
// @Success 200 {object} models.Label "The created label object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid label object provided."
// @Failure 400 {object} web.HTTPError "Invalid label object provided."
// @Failure 500 {object} models.Message "Internal error"
// @Router /labels [put]
func (l *Label) Create(a web.Auth) (err error) {
@ -86,9 +86,9 @@ func (l *Label) Create(a web.Auth) (err error) {
// @Param id path int true "Label ID"
// @Param label body models.Label true "The label object"
// @Success 200 {object} models.Label "The created label object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid label object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "Not allowed to update the label."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "Label not found."
// @Failure 400 {object} web.HTTPError "Invalid label object provided."
// @Failure 403 {object} web.HTTPError "Not allowed to update the label."
// @Failure 404 {object} web.HTTPError "Label not found."
// @Failure 500 {object} models.Message "Internal error"
// @Router /labels/{id} [put]
func (l *Label) Update() (err error) {
@ -110,8 +110,8 @@ func (l *Label) Update() (err error) {
// @Security JWTKeyAuth
// @Param id path int true "Label ID"
// @Success 200 {object} models.Label "The label was successfully deleted."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "Not allowed to delete the label."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "Label not found."
// @Failure 403 {object} web.HTTPError "Not allowed to delete the label."
// @Failure 404 {object} web.HTTPError "Label not found."
// @Failure 500 {object} models.Message "Internal error"
// @Router /labels/{id} [delete]
func (l *Label) Delete() (err error) {
@ -165,8 +165,8 @@ func (l *Label) ReadAll(a web.Auth, search string, page int, perPage int) (ls in
// @Param id path int true "Label ID"
// @Security JWTKeyAuth
// @Success 200 {object} models.Label "The label"
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the label"
// @Failure 404 {object} code.vikunja.io/web.HTTPError "Label not found"
// @Failure 403 {object} web.HTTPError "The user does not have access to the label"
// @Failure 404 {object} web.HTTPError "Label not found"
// @Failure 500 {object} models.Message "Internal error"
// @Router /labels/{id} [get]
func (l *Label) ReadOne() (err error) {

View File

@ -52,8 +52,8 @@ func (LabelTask) TableName() string {
// @Param task path int true "Task ID"
// @Param label path int true "Label ID"
// @Success 200 {object} models.Message "The label was successfully removed."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "Not allowed to remove the label."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "Label not found."
// @Failure 403 {object} web.HTTPError "Not allowed to remove the label."
// @Failure 404 {object} web.HTTPError "Label not found."
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{task}/labels/{label} [delete]
func (lt *LabelTask) Delete() (err error) {
@ -71,9 +71,9 @@ func (lt *LabelTask) Delete() (err error) {
// @Param task path int true "Task ID"
// @Param label body models.LabelTask true "The label object"
// @Success 200 {object} models.LabelTask "The created label relation object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid label object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "Not allowed to add the label."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "The label does not exist."
// @Failure 400 {object} web.HTTPError "Invalid label object provided."
// @Failure 403 {object} web.HTTPError "Not allowed to add the label."
// @Failure 404 {object} web.HTTPError "The label does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{task}/labels [put]
func (lt *LabelTask) Create(a web.Auth) (err error) {
@ -336,7 +336,7 @@ type LabelTaskBulk struct {
// @Param label body models.LabelTaskBulk true "The array of labels"
// @Param taskID path int true "Task ID"
// @Success 200 {object} models.LabelTaskBulk "The updated labels object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid label object provided."
// @Failure 400 {object} web.HTTPError "Invalid label object provided."
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{taskID}/labels/bulk [post]
func (ltb *LabelTaskBulk) Create(a web.Auth) (err error) {

View File

@ -93,9 +93,9 @@ func GetLinkShareFromClaims(claims jwt.MapClaims) (share *LinkSharing, err error
// @Param list path int true "List ID"
// @Param label body models.LinkSharing true "The new link share object"
// @Success 200 {object} models.LinkSharing "The created link share object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid link share object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "Not allowed to add the list share."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "The list does not exist."
// @Failure 400 {object} web.HTTPError "Invalid link share object provided."
// @Failure 403 {object} web.HTTPError "Not allowed to add the list share."
// @Failure 404 {object} web.HTTPError "The list does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{list}/shares [put]
func (share *LinkSharing) Create(a web.Auth) (err error) {
@ -116,8 +116,8 @@ func (share *LinkSharing) Create(a web.Auth) (err error) {
// @Param share path int true "Share ID"
// @Security JWTKeyAuth
// @Success 200 {object} models.LinkSharing "The share links"
// @Failure 403 {object} code.vikunja.io/web.HTTPError "No access to the list"
// @Failure 404 {object} code.vikunja.io/web.HTTPError "Share Link not found."
// @Failure 403 {object} web.HTTPError "No access to the list"
// @Failure 404 {object} web.HTTPError "Share Link not found."
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{list}/shares/{share} [get]
func (share *LinkSharing) ReadOne() (err error) {
@ -205,8 +205,8 @@ func (share *LinkSharing) ReadAll(a web.Auth, search string, page int, perPage i
// @Param list path int true "List ID"
// @Param share path int true "Share Link ID"
// @Success 200 {object} models.Message "The link was successfully removed."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "Not allowed to remove the link."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "Share Link not found."
// @Failure 403 {object} web.HTTPError "Not allowed to remove the link."
// @Failure 404 {object} web.HTTPError "Share Link not found."
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{list}/shares/{share} [delete]
func (share *LinkSharing) Delete() (err error) {

View File

@ -103,7 +103,7 @@ func GetListsByNamespaceID(nID int64, doer *user.User) (lists []*List, err error
// @Param is_archived query bool false "If true, also returns all archived lists."
// @Security JWTKeyAuth
// @Success 200 {array} models.List "The lists"
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the list"
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists [get]
func (l *List) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, totalItems int64, err error) {
@ -145,7 +145,7 @@ func (l *List) ReadAll(a web.Auth, search string, page int, perPage int) (result
// @Security JWTKeyAuth
// @Param id path int true "List ID"
// @Success 200 {object} models.List "The list"
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the list"
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{id} [get]
func (l *List) ReadOne() (err error) {
@ -425,8 +425,8 @@ func CreateOrUpdateList(list *List) (err error) {
// @Param id path int true "List ID"
// @Param list body models.List true "The list with updated values you want to update."
// @Success 200 {object} models.List "The updated list."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid list object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the list"
// @Failure 400 {object} web.HTTPError "Invalid list object provided."
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{id} [post]
func (l *List) Update() (err error) {
@ -458,8 +458,8 @@ func updateListByTaskID(taskID int64) (err error) {
// @Param namespaceID path int true "Namespace ID"
// @Param list body models.List true "The list you want to create."
// @Success 200 {object} models.List "The created list."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid list object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the list"
// @Failure 400 {object} web.HTTPError "Invalid list object provided."
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespaces/{namespaceID}/lists [put]
func (l *List) Create(a web.Auth) (err error) {
@ -488,8 +488,8 @@ func (l *List) Create(a web.Auth) (err error) {
// @Security JWTKeyAuth
// @Param id path int true "List ID"
// @Success 200 {object} models.Message "The list was successfully deleted."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid list object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the list"
// @Failure 400 {object} web.HTTPError "Invalid list object provided."
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{id} [delete]
func (l *List) Delete() (err error) {

View File

@ -62,9 +62,9 @@ type TeamWithRight struct {
// @Param id path int true "List ID"
// @Param list body models.TeamList true "The team you want to add to the list."
// @Success 200 {object} models.TeamList "The created team<->list relation."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid team list object provided."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "The team does not exist."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the list"
// @Failure 400 {object} web.HTTPError "Invalid team list object provided."
// @Failure 404 {object} web.HTTPError "The team does not exist."
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{id}/teams [put]
func (tl *TeamList) Create(a web.Auth) (err error) {
@ -116,8 +116,8 @@ func (tl *TeamList) Create(a web.Auth) (err error) {
// @Param listID path int true "List ID"
// @Param teamID path int true "Team ID"
// @Success 200 {object} models.Message "The team was successfully deleted."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the list"
// @Failure 404 {object} code.vikunja.io/web.HTTPError "Team or list does not exist."
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
// @Failure 404 {object} web.HTTPError "Team or list does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{listID}/teams/{teamID} [delete]
func (tl *TeamList) Delete() (err error) {
@ -162,7 +162,7 @@ func (tl *TeamList) Delete() (err error) {
// @Param s query string false "Search teams by its name."
// @Security JWTKeyAuth
// @Success 200 {array} models.TeamWithRight "The teams with their right."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "No right to see the list."
// @Failure 403 {object} web.HTTPError "No right to see the list."
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{id}/teams [get]
func (tl *TeamList) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, totalItems int64, err error) {
@ -227,8 +227,8 @@ func (tl *TeamList) ReadAll(a web.Auth, search string, page int, perPage int) (r
// @Param list body models.TeamList true "The team you want to update."
// @Security JWTKeyAuth
// @Success 200 {object} models.TeamList "The updated team <-> list relation."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have admin-access to the list"
// @Failure 404 {object} code.vikunja.io/web.HTTPError "Team or list does not exist."
// @Failure 403 {object} web.HTTPError "The user does not have admin-access to the list"
// @Failure 404 {object} web.HTTPError "Team or list does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{listID}/teams/{teamID} [post]
func (tl *TeamList) Update() (err error) {

View File

@ -65,9 +65,9 @@ type UserWithRight struct {
// @Param id path int true "List ID"
// @Param list body models.ListUser true "The user you want to add to the list."
// @Success 200 {object} models.ListUser "The created user<->list relation."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid user list object provided."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "The user does not exist."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the list"
// @Failure 400 {object} web.HTTPError "Invalid user list object provided."
// @Failure 404 {object} web.HTTPError "The user does not exist."
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{id}/users [put]
func (lu *ListUser) Create(a web.Auth) (err error) {
@ -123,8 +123,8 @@ func (lu *ListUser) Create(a web.Auth) (err error) {
// @Param listID path int true "List ID"
// @Param userID path int true "User ID"
// @Success 200 {object} models.Message "The user was successfully removed from the list."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the list"
// @Failure 404 {object} code.vikunja.io/web.HTTPError "user or list does not exist."
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
// @Failure 404 {object} web.HTTPError "user or list does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{listID}/users/{userID} [delete]
func (lu *ListUser) Delete() (err error) {
@ -168,7 +168,7 @@ func (lu *ListUser) Delete() (err error) {
// @Param s query string false "Search users by its name."
// @Security JWTKeyAuth
// @Success 200 {array} models.UserWithRight "The users with the right they have."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "No right to see the list."
// @Failure 403 {object} web.HTTPError "No right to see the list."
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{id}/users [get]
func (lu *ListUser) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, numberOfTotalItems int64, err error) {
@ -223,8 +223,8 @@ func (lu *ListUser) ReadAll(a web.Auth, search string, page int, perPage int) (r
// @Param list body models.ListUser true "The user you want to update."
// @Security JWTKeyAuth
// @Success 200 {object} models.ListUser "The updated user <-> list relation."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have admin-access to the list"
// @Failure 404 {object} code.vikunja.io/web.HTTPError "User or list does not exist."
// @Failure 403 {object} web.HTTPError "The user does not have admin-access to the list"
// @Failure 404 {object} web.HTTPError "User or list does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{listID}/users/{userID} [post]
func (lu *ListUser) Update() (err error) {

View File

@ -133,7 +133,7 @@ func (n *Namespace) CheckIsArchived() error {
// @Security JWTKeyAuth
// @Param id path int true "Namespace ID"
// @Success 200 {object} models.Namespace "The Namespace"
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to that namespace."
// @Failure 403 {object} web.HTTPError "The user does not have access to that namespace."
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespaces/{id} [get]
func (n *Namespace) ReadOne() (err error) {
@ -335,8 +335,8 @@ func (n *Namespace) ReadAll(a web.Auth, search string, page int, perPage int) (r
// @Security JWTKeyAuth
// @Param namespace body models.Namespace true "The namespace you want to create."
// @Success 200 {object} models.Namespace "The created namespace."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid namespace object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the namespace"
// @Failure 400 {object} web.HTTPError "Invalid namespace object provided."
// @Failure 403 {object} web.HTTPError "The user does not have access to the namespace"
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespaces [put]
func (n *Namespace) Create(a web.Auth) (err error) {
@ -370,8 +370,8 @@ func (n *Namespace) Create(a web.Auth) (err error) {
// @Security JWTKeyAuth
// @Param id path int true "Namespace ID"
// @Success 200 {object} models.Message "The namespace was successfully deleted."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid namespace object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the namespace"
// @Failure 400 {object} web.HTTPError "Invalid namespace object provided."
// @Failure 403 {object} web.HTTPError "The user does not have access to the namespace"
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespaces/{id} [delete]
func (n *Namespace) Delete() (err error) {
@ -428,8 +428,8 @@ func (n *Namespace) Delete() (err error) {
// @Param id path int true "Namespace ID"
// @Param namespace body models.Namespace true "The namespace with updated values you want to update."
// @Success 200 {object} models.Namespace "The updated namespace."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid namespace object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the namespace"
// @Failure 400 {object} web.HTTPError "Invalid namespace object provided."
// @Failure 403 {object} web.HTTPError "The user does not have access to the namespace"
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespace/{id} [post]
func (n *Namespace) Update() (err error) {

View File

@ -56,9 +56,9 @@ func (TeamNamespace) TableName() string {
// @Param id path int true "Namespace ID"
// @Param namespace body models.TeamNamespace true "The team you want to add to the namespace."
// @Success 200 {object} models.TeamNamespace "The created team<->namespace relation."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid team namespace object provided."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "The team does not exist."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The team does not have access to the namespace"
// @Failure 400 {object} web.HTTPError "Invalid team namespace object provided."
// @Failure 404 {object} web.HTTPError "The team does not exist."
// @Failure 403 {object} web.HTTPError "The team does not have access to the namespace"
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespaces/{id}/teams [put]
func (tn *TeamNamespace) Create(a web.Auth) (err error) {
@ -105,8 +105,8 @@ func (tn *TeamNamespace) Create(a web.Auth) (err error) {
// @Param namespaceID path int true "Namespace ID"
// @Param teamID path int true "team ID"
// @Success 200 {object} models.Message "The team was successfully deleted."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The team does not have access to the namespace"
// @Failure 404 {object} code.vikunja.io/web.HTTPError "team or namespace does not exist."
// @Failure 403 {object} web.HTTPError "The team does not have access to the namespace"
// @Failure 404 {object} web.HTTPError "team or namespace does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespaces/{namespaceID}/teams/{teamID} [delete]
func (tn *TeamNamespace) Delete() (err error) {
@ -147,7 +147,7 @@ func (tn *TeamNamespace) Delete() (err error) {
// @Param s query string false "Search teams by its name."
// @Security JWTKeyAuth
// @Success 200 {array} models.TeamWithRight "The teams with the right they have."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "No right to see the namespace."
// @Failure 403 {object} web.HTTPError "No right to see the namespace."
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespaces/{id}/teams [get]
func (tn *TeamNamespace) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, numberOfTotalItems int64, err error) {
@ -208,8 +208,8 @@ func (tn *TeamNamespace) ReadAll(a web.Auth, search string, page int, perPage in
// @Param namespace body models.TeamNamespace true "The team you want to update."
// @Security JWTKeyAuth
// @Success 200 {object} models.TeamNamespace "The updated team <-> namespace relation."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The team does not have admin-access to the namespace"
// @Failure 404 {object} code.vikunja.io/web.HTTPError "Team or namespace does not exist."
// @Failure 403 {object} web.HTTPError "The team does not have admin-access to the namespace"
// @Failure 404 {object} web.HTTPError "Team or namespace does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespaces/{namespaceID}/teams/{teamID} [post]
func (tn *TeamNamespace) Update() (err error) {

View File

@ -58,9 +58,9 @@ func (NamespaceUser) TableName() string {
// @Param id path int true "Namespace ID"
// @Param namespace body models.NamespaceUser true "The user you want to add to the namespace."
// @Success 200 {object} models.NamespaceUser "The created user<->namespace relation."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid user namespace object provided."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "The user does not exist."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the namespace"
// @Failure 400 {object} web.HTTPError "Invalid user namespace object provided."
// @Failure 404 {object} web.HTTPError "The user does not exist."
// @Failure 403 {object} web.HTTPError "The user does not have access to the namespace"
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespaces/{id}/users [put]
func (nu *NamespaceUser) Create(a web.Auth) (err error) {
@ -114,8 +114,8 @@ func (nu *NamespaceUser) Create(a web.Auth) (err error) {
// @Param namespaceID path int true "Namespace ID"
// @Param userID path int true "user ID"
// @Success 200 {object} models.Message "The user was successfully deleted."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the namespace"
// @Failure 404 {object} code.vikunja.io/web.HTTPError "user or namespace does not exist."
// @Failure 403 {object} web.HTTPError "The user does not have access to the namespace"
// @Failure 404 {object} web.HTTPError "user or namespace does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespaces/{namespaceID}/users/{userID} [delete]
func (nu *NamespaceUser) Delete() (err error) {
@ -154,7 +154,7 @@ func (nu *NamespaceUser) Delete() (err error) {
// @Param s query string false "Search users by its name."
// @Security JWTKeyAuth
// @Success 200 {array} models.UserWithRight "The users with the right they have."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "No right to see the namespace."
// @Failure 403 {object} web.HTTPError "No right to see the namespace."
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespaces/{id}/users [get]
func (nu *NamespaceUser) ReadAll(a web.Auth, search string, page int, perPage int) (result interface{}, resultCount int, numberOfTotalItems int64, err error) {
@ -210,8 +210,8 @@ func (nu *NamespaceUser) ReadAll(a web.Auth, search string, page int, perPage in
// @Param namespace body models.NamespaceUser true "The user you want to update."
// @Security JWTKeyAuth
// @Success 200 {object} models.NamespaceUser "The updated user <-> namespace relation."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have admin-access to the namespace"
// @Failure 404 {object} code.vikunja.io/web.HTTPError "User or namespace does not exist."
// @Failure 403 {object} web.HTTPError "The user does not have admin-access to the namespace"
// @Failure 404 {object} web.HTTPError "User or namespace does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /namespaces/{namespaceID}/users/{userID} [post]
func (nu *NamespaceUser) Update() (err error) {

View File

@ -162,7 +162,7 @@ func (t *Task) setTaskAssignees(assignees []*user.User) {
// @Param taskID path int true "Task ID"
// @Param userID path int true "Assignee user ID"
// @Success 200 {object} models.Message "The assignee was successfully deleted."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "Not allowed to delete the assignee."
// @Failure 403 {object} web.HTTPError "Not allowed to delete the assignee."
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{taskID}/assignees/{userID} [delete]
func (la *TaskAssginee) Delete() (err error) {
@ -185,7 +185,7 @@ func (la *TaskAssginee) Delete() (err error) {
// @Param assignee body models.TaskAssginee true "The assingee object"
// @Param taskID path int true "Task ID"
// @Success 200 {object} models.TaskAssginee "The created assingee object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid assignee object provided."
// @Failure 400 {object} web.HTTPError "Invalid assignee object provided."
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{taskID}/assignees [put]
func (la *TaskAssginee) Create(a web.Auth) (err error) {
@ -296,7 +296,7 @@ type BulkAssignees struct {
// @Param assignee body models.BulkAssignees true "The array of assignees"
// @Param taskID path int true "Task ID"
// @Success 200 {object} models.TaskAssginee "The created assingees object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid assignee object provided."
// @Failure 400 {object} web.HTTPError "Invalid assignee object provided."
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{taskID}/assignees/bulk [post]
func (ba *BulkAssignees) Create(a web.Auth) (err error) {

View File

@ -53,7 +53,7 @@ func (tc *TaskComment) TableName() string {
// @Param relation body models.TaskComment true "The task comment object"
// @Param taskID path int true "Task ID"
// @Success 200 {object} models.TaskComment "The created task comment object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid task comment object provided."
// @Failure 400 {object} web.HTTPError "Invalid task comment object provided."
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{taskID}/comments [put]
func (tc *TaskComment) Create(a web.Auth) (err error) {
@ -82,8 +82,8 @@ func (tc *TaskComment) Create(a web.Auth) (err error) {
// @Param taskID path int true "Task ID"
// @Param commentID path int true "Comment ID"
// @Success 200 {object} models.Message "The task comment was successfully deleted."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid task comment object provided."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "The task comment was not found."
// @Failure 400 {object} web.HTTPError "Invalid task comment object provided."
// @Failure 404 {object} web.HTTPError "The task comment was not found."
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{taskID}/comments/{commentID} [delete]
func (tc *TaskComment) Delete() error {
@ -104,8 +104,8 @@ func (tc *TaskComment) Delete() error {
// @Param taskID path int true "Task ID"
// @Param commentID path int true "Comment ID"
// @Success 200 {object} models.TaskComment "The updated task comment object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid task comment object provided."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "The task comment was not found."
// @Failure 400 {object} web.HTTPError "Invalid task comment object provided."
// @Failure 404 {object} web.HTTPError "The task comment was not found."
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{taskID}/comments/{commentID} [post]
func (tc *TaskComment) Update() error {
@ -126,8 +126,8 @@ func (tc *TaskComment) Update() error {
// @Param taskID path int true "Task ID"
// @Param commentID path int true "Comment ID"
// @Success 200 {object} models.TaskComment "The task comment object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid task comment object provided."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "The task comment was not found."
// @Failure 400 {object} web.HTTPError "Invalid task comment object provided."
// @Failure 404 {object} web.HTTPError "The task comment was not found."
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{taskID}/comments/{commentID} [get]
func (tc *TaskComment) ReadOne() (err error) {

View File

@ -113,7 +113,7 @@ type RelatedTaskMap map[RelationKind][]*Task
// @Param relation body models.TaskRelation true "The relation object"
// @Param taskID path int true "Task ID"
// @Success 200 {object} models.TaskRelation "The created task relation object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid task relation object provided."
// @Failure 400 {object} web.HTTPError "Invalid task relation object provided."
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{taskID}/relations [put]
func (rel *TaskRelation) Create(a web.Auth) error {
@ -193,8 +193,8 @@ func (rel *TaskRelation) Create(a web.Auth) error {
// @Param relation body models.TaskRelation true "The relation object"
// @Param taskID path int true "Task ID"
// @Success 200 {object} models.Message "The task relation was successfully deleted."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid task relation object provided."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "The task relation was not found."
// @Failure 400 {object} web.HTTPError "Invalid task relation object provided."
// @Failure 404 {object} web.HTTPError "The task relation was not found."
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{taskID}/relations [delete]
func (rel *TaskRelation) Delete() error {

View File

@ -469,8 +469,8 @@ func addMoreInfoToTasks(taskMap map[int64]*Task) (tasks []*Task, err error) {
// @Param id path int true "List ID"
// @Param task body models.Task true "The task object"
// @Success 200 {object} models.Task "The created task object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid task object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the list"
// @Failure 400 {object} web.HTTPError "Invalid task object provided."
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
// @Failure 500 {object} models.Message "Internal error"
// @Router /lists/{id} [put]
func (t *Task) Create(a web.Auth) (err error) {
@ -538,8 +538,8 @@ func (t *Task) Create(a web.Auth) (err error) {
// @Param id path int true "Task ID"
// @Param task body models.Task true "The task object"
// @Success 200 {object} models.Task "The updated task object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid task object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the task (aka its list)"
// @Failure 400 {object} web.HTTPError "Invalid task object provided."
// @Failure 403 {object} web.HTTPError "The user does not have access to the task (aka its list)"
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{id} [post]
func (t *Task) Update() (err error) {
@ -796,8 +796,8 @@ func (t *Task) updateReminders(reminders []timeutil.TimeStamp) (err error) {
// @Security JWTKeyAuth
// @Param id path int true "Task ID"
// @Success 200 {object} models.Message "The created task object."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid task ID provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the list"
// @Failure 400 {object} web.HTTPError "Invalid task ID provided."
// @Failure 403 {object} web.HTTPError "The user does not have access to the list"
// @Failure 500 {object} models.Message "Internal error"
// @Router /tasks/{id} [delete]
func (t *Task) Delete() (err error) {

View File

@ -31,8 +31,8 @@ import (
// @Param id path int true "Team ID"
// @Param team body models.TeamMember true "The user to be added to a team."
// @Success 200 {object} models.TeamMember "The newly created member object"
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid member object provided."
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the team"
// @Failure 400 {object} web.HTTPError "Invalid member object provided."
// @Failure 403 {object} web.HTTPError "The user does not have access to the team"
// @Failure 500 {object} models.Message "Internal error"
// @Router /teams/{id}/members [put]
func (tm *TeamMember) Create(a web.Auth) (err error) {

View File

@ -174,7 +174,7 @@ func addMoreInfoToTeams(teams []*Team) (err error) {
// @Security JWTKeyAuth
// @Param id path int true "Team ID"
// @Success 200 {object} models.Team "The team"
// @Failure 403 {object} code.vikunja.io/web.HTTPError "The user does not have access to the team"
// @Failure 403 {object} web.HTTPError "The user does not have access to the team"
// @Failure 500 {object} models.Message "Internal error"
// @Router /teams/{id} [get]
func (t *Team) ReadOne() (err error) {
@ -242,7 +242,7 @@ func (t *Team) ReadAll(a web.Auth, search string, page int, perPage int) (result
// @Security JWTKeyAuth
// @Param team body models.Team true "The team you want to create."
// @Success 200 {object} models.Team "The created team."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid team object provided."
// @Failure 400 {object} web.HTTPError "Invalid team object provided."
// @Failure 500 {object} models.Message "Internal error"
// @Router /teams [put]
func (t *Team) Create(a web.Auth) (err error) {
@ -282,7 +282,7 @@ func (t *Team) Create(a web.Auth) (err error) {
// @Security JWTKeyAuth
// @Param id path int true "Team ID"
// @Success 200 {object} models.Message "The team was successfully deleted."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid team object provided."
// @Failure 400 {object} web.HTTPError "Invalid team object provided."
// @Failure 500 {object} models.Message "Internal error"
// @Router /teams/{id} [delete]
func (t *Team) Delete() (err error) {
@ -325,7 +325,7 @@ func (t *Team) Delete() (err error) {
// @Param id path int true "Team ID"
// @Param team body models.Team true "The team with updated values you want to update."
// @Success 200 {object} models.Team "The updated team."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid team object provided."
// @Failure 400 {object} web.HTTPError "Invalid team object provided."
// @Failure 500 {object} models.Message "Internal error"
// @Router /teams/{id} [post]
func (t *Team) Update() (err error) {

View File

@ -18,6 +18,7 @@ package v1
import (
"code.vikunja.io/api/pkg/models"
_ "code.vikunja.io/web"
"code.vikunja.io/web/handler"
"github.com/labstack/echo/v4"
"net/http"
@ -38,7 +39,7 @@ type LinkShareToken struct {
// @Produce json
// @Param share path string true "The share hash"
// @Success 200 {object} v1.Token "The valid jwt auth token."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Invalid link share object provided."
// @Failure 400 {object} web.HTTPError "Invalid link share object provided."
// @Failure 500 {object} models.Message "Internal error"
// @Router /shares/{share}/auth [post]
func AuthenticateLinkShare(c echo.Context) error {

View File

@ -20,6 +20,7 @@ import (
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/user"
_ "code.vikunja.io/web"
"code.vikunja.io/web/handler"
"github.com/labstack/echo/v4"
"net/http"
@ -33,7 +34,7 @@ import (
// @Produce json
// @Param credentials body user.APIUserPassword true "The user credentials"
// @Success 200 {object} user.User
// @Failure 400 {object} code.vikunja.io/web.HTTPError "No or invalid user register object provided / User already exists."
// @Failure 400 {object} web.HTTPError "No or invalid user register object provided / User already exists."
// @Failure 500 {object} models.Message "Internal error"
// @Router /register [post]
func RegisterUser(c echo.Context) error {

View File

@ -19,6 +19,7 @@ package v1
import (
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/user"
_ "code.vikunja.io/web"
"code.vikunja.io/web/handler"
"github.com/labstack/echo/v4"
"net/http"
@ -32,7 +33,7 @@ import (
// @Produce json
// @Param credentials body models.EmailConfirm true "The token."
// @Success 200 {object} models.Message
// @Failure 412 {object} code.vikunja.io/web.HTTPError "Bad token provided."
// @Failure 412 {object} web.HTTPError "Bad token provided."
// @Failure 500 {object} models.Message "Internal error"
// @Router /user/confirm [post]
func UserConfirmEmail(c echo.Context) error {

View File

@ -19,6 +19,7 @@ package v1
import (
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/user"
_ "code.vikunja.io/web"
"code.vikunja.io/web/handler"
"github.com/labstack/echo/v4"
"net/http"
@ -34,7 +35,7 @@ import (
// @Param s query string false "Search for a user by its name."
// @Security JWTKeyAuth
// @Success 200 {array} user.User "All (found) users."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Something's invalid."
// @Failure 400 {object} web.HTTPError "Something's invalid."
// @Failure 500 {object} models.Message "Internal server error."
// @Router /users [get]
func UserList(c echo.Context) error {
@ -62,8 +63,8 @@ func UserList(c echo.Context) error {
// @Security JWTKeyAuth
// @Param id path int true "List ID"
// @Success 200 {array} user.User "All (found) users."
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Something's invalid."
// @Failure 401 {object} code.vikunja.io/web.HTTPError "The user does not have the right to see the list."
// @Failure 400 {object} web.HTTPError "Something's invalid."
// @Failure 401 {object} web.HTTPError "The user does not have the right to see the list."
// @Failure 500 {object} models.Message "Internal server error."
// @Router /lists/{id}/listusers [get]
func ListUsersForList(c echo.Context) error {

View File

@ -19,6 +19,7 @@ package v1
import (
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/user"
_ "code.vikunja.io/web"
"code.vikunja.io/web/handler"
"github.com/labstack/echo/v4"
"net/http"
@ -32,7 +33,7 @@ import (
// @Produce json
// @Param credentials body models.PasswordReset true "The token with the new password."
// @Success 200 {object} models.Message
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Bad token provided."
// @Failure 400 {object} web.HTTPError "Bad token provided."
// @Failure 500 {object} models.Message "Internal error"
// @Router /user/password/reset [post]
func UserResetPassword(c echo.Context) error {
@ -58,7 +59,7 @@ func UserResetPassword(c echo.Context) error {
// @Produce json
// @Param credentials body models.PasswordTokenRequest true "The username of the user to request a token for."
// @Success 200 {object} models.Message
// @Failure 404 {object} code.vikunja.io/web.HTTPError "The user does not exist."
// @Failure 404 {object} web.HTTPError "The user does not exist."
// @Failure 500 {object} models.Message "Internal error"
// @Router /user/password/token [post]
func UserRequestResetPasswordToken(c echo.Context) error {

View File

@ -18,6 +18,7 @@ package v1
import (
user2 "code.vikunja.io/api/pkg/user"
_ "code.vikunja.io/web"
"code.vikunja.io/web/handler"
"github.com/labstack/echo/v4"
"net/http"
@ -31,7 +32,7 @@ import (
// @Produce json
// @Security JWTKeyAuth
// @Success 200 {object} user.User
// @Failure 404 {object} code.vikunja.io/web.HTTPError "User does not exist."
// @Failure 404 {object} web.HTTPError "User does not exist."
// @Failure 500 {object} models.Message "Internal server error."
// @Router /user [get]
func UserShow(c echo.Context) error {

View File

@ -19,6 +19,7 @@ package v1
import (
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/user"
_ "code.vikunja.io/web"
"code.vikunja.io/web/handler"
"github.com/labstack/echo/v4"
"net/http"
@ -39,8 +40,8 @@ type UserPassword struct {
// @Param userPassword body v1.UserPassword true "The current and new password."
// @Security JWTKeyAuth
// @Success 200 {object} models.Message
// @Failure 400 {object} code.vikunja.io/web.HTTPError "Something's invalid."
// @Failure 404 {object} code.vikunja.io/web.HTTPError "User does not exist."
// @Failure 400 {object} web.HTTPError "Something's invalid."
// @Failure 404 {object} web.HTTPError "User does not exist."
// @Failure 500 {object} models.Message "Internal server error."
// @Router /user/password [post]
func UserChangePassword(c echo.Context) error {

View File

@ -21,3 +21,8 @@ linters:
- lll
- gochecknoinits
- gochecknoglobals
- funlen
- godox
- gocognit
- whitespace
- wsl

View File

@ -1,12 +1,10 @@
after_success:
- bash <(curl -s https://codecov.io/bash)
go:
- 1.11.x
- 1.12.x
- 1.13.x
- 1.14.x
install:
- GO111MODULE=off go get -u gotest.tools/gotestsum
env:
- GO111MODULE=on
language: go
notifications:
slack:

View File

@ -14,11 +14,41 @@
package spec
import (
"encoding/json"
"github.com/go-openapi/swag"
)
// ContactInfo contact information for the exposed API.
//
// For more information: http://goo.gl/8us55a#contactObject
type ContactInfo struct {
ContactInfoProps
VendorExtensible
}
type ContactInfoProps struct {
Name string `json:"name,omitempty"`
URL string `json:"url,omitempty"`
Email string `json:"email,omitempty"`
}
func (c *ContactInfo) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &c.ContactInfoProps); err != nil {
return err
}
return json.Unmarshal(data, &c.VendorExtensible)
}
func (c ContactInfo) MarshalJSON() ([]byte, error) {
b1, err := json.Marshal(c.ContactInfoProps)
if err != nil {
return nil, err
}
b2, err := json.Marshal(c.VendorExtensible)
if err != nil {
return nil, err
}
return swag.ConcatJSON(b1, b2), nil
}

View File

@ -452,11 +452,12 @@ func expandPathItem(pathItem *PathItem, resolver *schemaLoader, basePath string)
return err
}
if pathItem.Ref.String() != "" {
var err error
resolver, err = resolver.transitiveResolver(basePath, pathItem.Ref)
if resolver.shouldStopOnError(err) {
transitiveResolver, err := resolver.transitiveResolver(basePath, pathItem.Ref)
if transitiveResolver.shouldStopOnError(err) {
return err
}
basePath = transitiveResolver.updateBasePath(resolver, basePath)
resolver = transitiveResolver
}
pathItem.Ref = Ref{}

View File

@ -4,14 +4,9 @@ require (
github.com/go-openapi/jsonpointer v0.19.3
github.com/go-openapi/jsonreference v0.19.2
github.com/go-openapi/swag v0.19.5
github.com/kr/pty v1.1.5 // indirect
github.com/stretchr/objx v0.2.0 // indirect
github.com/stretchr/testify v1.3.0
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 // indirect
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 // indirect
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f // indirect
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 // indirect
gopkg.in/yaml.v2 v2.2.2
gopkg.in/yaml.v2 v2.2.4
)
go 1.13

View File

@ -1,5 +1,3 @@
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=
@ -7,20 +5,12 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko
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/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.19.0 h1:FTUMcX77w5rQkClIzDtTxvn6Bsa894CcrzNj2MMfeg8=
github.com/go-openapi/jsonpointer v0.19.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.19.2 h1:A9+F4Dc/MCNB5jibxf6rRvOvR/iFgQdyNx9eIhnGqq0=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
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/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
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.19.2 h1:jvO6bCMBEilGwMfHhrd61zIID4oIFdwb76V17SM88dE=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
@ -28,11 +18,8 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
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/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
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-20190614124828-94de47d64c63 h1:nTT4s92Dgz2HlrB2NaMgvlfqHH39OgMhA7z3PK7PGD4=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
@ -40,35 +27,23 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
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=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
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-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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-20190614205625-5aca471b1d59/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/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=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -14,10 +14,40 @@
package spec
import (
"encoding/json"
"github.com/go-openapi/swag"
)
// License information for the exposed API.
//
// For more information: http://goo.gl/8us55a#licenseObject
type License struct {
LicenseProps
VendorExtensible
}
type LicenseProps struct {
Name string `json:"name,omitempty"`
URL string `json:"url,omitempty"`
}
func (l *License) UnmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, &l.LicenseProps); err != nil {
return err
}
return json.Unmarshal(data, &l.VendorExtensible)
}
func (l License) MarshalJSON() ([]byte, error) {
b1, err := json.Marshal(l.LicenseProps)
if err != nil {
return nil, err
}
b2, err := json.Marshal(l.VendorExtensible)
if err != nil {
return nil, err
}
return swag.ConcatJSON(b1, b2), nil
}

View File

@ -68,6 +68,7 @@ func (r *Ref) IsValidURI(basepaths ...string) bool {
}
if r.HasFullURL {
//#nosec
rr, err := http.Get(v)
if err != nil {
return false

View File

@ -86,12 +86,7 @@ func (r *schemaLoader) transitiveResolver(basePath string, ref Ref) (*schemaLoad
newOptions := r.options
newOptions.RelativeBase = rootURL.String()
debugLog("setting new root: %s", newOptions.RelativeBase)
resolver, err := defaultSchemaLoader(root, newOptions, r.cache, r.context)
if err != nil {
return nil, err
}
return resolver, nil
return defaultSchemaLoader(root, newOptions, r.cache, r.context)
}
func (r *schemaLoader) updateBasePath(transitive *schemaLoader, basePath string) string {

View File

@ -1,12 +1,10 @@
after_success:
- bash <(curl -s https://codecov.io/bash)
go:
- 1.11.x
- 1.12.x
- 1.13.x
- 1.14.x
install:
- GO111MODULE=off go get -u gotest.tools/gotestsum
env:
- GO111MODULE=on
language: go
notifications:
slack:

View File

@ -88,7 +88,7 @@ func ConvertFloat64(str string) (float64, error) {
return strconv.ParseFloat(str, 64)
}
// ConvertInt8 turn a string into int8 boolean
// ConvertInt8 turn a string into an int8
func ConvertInt8(str string) (int8, error) {
i, err := strconv.ParseInt(str, 10, 8)
if err != nil {
@ -97,7 +97,7 @@ func ConvertInt8(str string) (int8, error) {
return int8(i), nil
}
// ConvertInt16 turn a string into a int16
// ConvertInt16 turn a string into an int16
func ConvertInt16(str string) (int16, error) {
i, err := strconv.ParseInt(str, 10, 16)
if err != nil {
@ -106,7 +106,7 @@ func ConvertInt16(str string) (int16, error) {
return int16(i), nil
}
// ConvertInt32 turn a string into a int32
// ConvertInt32 turn a string into an int32
func ConvertInt32(str string) (int32, error) {
i, err := strconv.ParseInt(str, 10, 32)
if err != nil {
@ -115,12 +115,12 @@ func ConvertInt32(str string) (int32, error) {
return int32(i), nil
}
// ConvertInt64 turn a string into a int64
// ConvertInt64 turn a string into an int64
func ConvertInt64(str string) (int64, error) {
return strconv.ParseInt(str, 10, 64)
}
// ConvertUint8 turn a string into a uint8
// ConvertUint8 turn a string into an uint8
func ConvertUint8(str string) (uint8, error) {
i, err := strconv.ParseUint(str, 10, 8)
if err != nil {
@ -129,7 +129,7 @@ func ConvertUint8(str string) (uint8, error) {
return uint8(i), nil
}
// ConvertUint16 turn a string into a uint16
// ConvertUint16 turn a string into an uint16
func ConvertUint16(str string) (uint16, error) {
i, err := strconv.ParseUint(str, 10, 16)
if err != nil {
@ -138,7 +138,7 @@ func ConvertUint16(str string) (uint16, error) {
return uint16(i), nil
}
// ConvertUint32 turn a string into a uint32
// ConvertUint32 turn a string into an uint32
func ConvertUint32(str string) (uint32, error) {
i, err := strconv.ParseUint(str, 10, 32)
if err != nil {
@ -147,7 +147,7 @@ func ConvertUint32(str string) (uint32, error) {
return uint32(i), nil
}
// ConvertUint64 turn a string into a uint64
// ConvertUint64 turn a string into an uint64
func ConvertUint64(str string) (uint64, error) {
return strconv.ParseUint(str, 10, 64)
}

View File

@ -181,12 +181,12 @@ func IntValueMap(src map[string]*int) map[string]int {
return dst
}
// Int32 returns a pointer to of the int64 value passed in.
// Int32 returns a pointer to of the int32 value passed in.
func Int32(v int32) *int32 {
return &v
}
// Int32Value returns the value of the int64 pointer passed in or
// Int32Value returns the value of the int32 pointer passed in or
// 0 if the pointer is nil.
func Int32Value(v *int32) int32 {
if v != nil {
@ -195,7 +195,7 @@ func Int32Value(v *int32) int32 {
return 0
}
// Int32Slice converts a slice of int64 values into a slice of
// Int32Slice converts a slice of int32 values into a slice of
// int32 pointers
func Int32Slice(src []int32) []*int32 {
dst := make([]*int32, len(src))
@ -299,13 +299,13 @@ func Int64ValueMap(src map[string]*int64) map[string]int64 {
return dst
}
// Uint returns a pouinter to of the uint value passed in.
// Uint returns a pointer to of the uint value passed in.
func Uint(v uint) *uint {
return &v
}
// UintValue returns the value of the uint pouinter passed in or
// 0 if the pouinter is nil.
// UintValue returns the value of the uint pointer passed in or
// 0 if the pointer is nil.
func UintValue(v *uint) uint {
if v != nil {
return *v
@ -313,8 +313,8 @@ func UintValue(v *uint) uint {
return 0
}
// UintSlice converts a slice of uint values uinto a slice of
// uint pouinters
// UintSlice converts a slice of uint values into a slice of
// uint pointers
func UintSlice(src []uint) []*uint {
dst := make([]*uint, len(src))
for i := 0; i < len(src); i++ {
@ -323,7 +323,7 @@ func UintSlice(src []uint) []*uint {
return dst
}
// UintValueSlice converts a slice of uint pouinters uinto a slice of
// UintValueSlice converts a slice of uint pointers into a slice of
// uint values
func UintValueSlice(src []*uint) []uint {
dst := make([]uint, len(src))
@ -335,8 +335,8 @@ func UintValueSlice(src []*uint) []uint {
return dst
}
// UintMap converts a string map of uint values uinto a string
// map of uint pouinters
// UintMap converts a string map of uint values into a string
// map of uint pointers
func UintMap(src map[string]uint) map[string]*uint {
dst := make(map[string]*uint)
for k, val := range src {
@ -346,7 +346,7 @@ func UintMap(src map[string]uint) map[string]*uint {
return dst
}
// UintValueMap converts a string map of uint pouinters uinto a string
// UintValueMap converts a string map of uint pointers into a string
// map of uint values
func UintValueMap(src map[string]*uint) map[string]uint {
dst := make(map[string]uint)
@ -358,13 +358,13 @@ func UintValueMap(src map[string]*uint) map[string]uint {
return dst
}
// Uint32 returns a pouinter to of the uint64 value passed in.
// Uint32 returns a pointer to of the uint32 value passed in.
func Uint32(v uint32) *uint32 {
return &v
}
// Uint32Value returns the value of the uint64 pouinter passed in or
// 0 if the pouinter is nil.
// Uint32Value returns the value of the uint32 pointer passed in or
// 0 if the pointer is nil.
func Uint32Value(v *uint32) uint32 {
if v != nil {
return *v
@ -372,8 +372,8 @@ func Uint32Value(v *uint32) uint32 {
return 0
}
// Uint32Slice converts a slice of uint64 values uinto a slice of
// uint32 pouinters
// Uint32Slice converts a slice of uint32 values into a slice of
// uint32 pointers
func Uint32Slice(src []uint32) []*uint32 {
dst := make([]*uint32, len(src))
for i := 0; i < len(src); i++ {
@ -382,7 +382,7 @@ func Uint32Slice(src []uint32) []*uint32 {
return dst
}
// Uint32ValueSlice converts a slice of uint32 pouinters uinto a slice of
// Uint32ValueSlice converts a slice of uint32 pointers into a slice of
// uint32 values
func Uint32ValueSlice(src []*uint32) []uint32 {
dst := make([]uint32, len(src))
@ -394,8 +394,8 @@ func Uint32ValueSlice(src []*uint32) []uint32 {
return dst
}
// Uint32Map converts a string map of uint32 values uinto a string
// map of uint32 pouinters
// Uint32Map converts a string map of uint32 values into a string
// map of uint32 pointers
func Uint32Map(src map[string]uint32) map[string]*uint32 {
dst := make(map[string]*uint32)
for k, val := range src {
@ -405,7 +405,7 @@ func Uint32Map(src map[string]uint32) map[string]*uint32 {
return dst
}
// Uint32ValueMap converts a string map of uint32 pouinters uinto a string
// Uint32ValueMap converts a string map of uint32 pointers into a string
// map of uint32 values
func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
dst := make(map[string]uint32)
@ -417,13 +417,13 @@ func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
return dst
}
// Uint64 returns a pouinter to of the uint64 value passed in.
// Uint64 returns a pointer to of the uint64 value passed in.
func Uint64(v uint64) *uint64 {
return &v
}
// Uint64Value returns the value of the uint64 pouinter passed in or
// 0 if the pouinter is nil.
// Uint64Value returns the value of the uint64 pointer passed in or
// 0 if the pointer is nil.
func Uint64Value(v *uint64) uint64 {
if v != nil {
return *v
@ -431,8 +431,8 @@ func Uint64Value(v *uint64) uint64 {
return 0
}
// Uint64Slice converts a slice of uint64 values uinto a slice of
// uint64 pouinters
// Uint64Slice converts a slice of uint64 values into a slice of
// uint64 pointers
func Uint64Slice(src []uint64) []*uint64 {
dst := make([]*uint64, len(src))
for i := 0; i < len(src); i++ {
@ -441,7 +441,7 @@ func Uint64Slice(src []uint64) []*uint64 {
return dst
}
// Uint64ValueSlice converts a slice of uint64 pouinters uinto a slice of
// Uint64ValueSlice converts a slice of uint64 pointers into a slice of
// uint64 values
func Uint64ValueSlice(src []*uint64) []uint64 {
dst := make([]uint64, len(src))
@ -453,8 +453,8 @@ func Uint64ValueSlice(src []*uint64) []uint64 {
return dst
}
// Uint64Map converts a string map of uint64 values uinto a string
// map of uint64 pouinters
// Uint64Map converts a string map of uint64 values into a string
// map of uint64 pointers
func Uint64Map(src map[string]uint64) map[string]*uint64 {
dst := make(map[string]*uint64)
for k, val := range src {
@ -464,7 +464,7 @@ func Uint64Map(src map[string]uint64) map[string]*uint64 {
return dst
}
// Uint64ValueMap converts a string map of uint64 pouinters uinto a string
// Uint64ValueMap converts a string map of uint64 pointers into a string
// map of uint64 values
func Uint64ValueMap(src map[string]*uint64) map[string]uint64 {
dst := make(map[string]uint64)

View File

@ -6,9 +6,11 @@ require (
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63
github.com/stretchr/testify v1.3.0
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/yaml.v2 v2.2.2
gopkg.in/yaml.v2 v2.2.4
)
replace github.com/golang/lint => golang.org/x/lint v0.0.0-20190409202823-959b441ac422
replace sourcegraph.com/sourcegraph/go-diff => github.com/sourcegraph/go-diff v0.5.1
go 1.13

View File

@ -16,5 +16,5 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
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/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -51,7 +51,7 @@ type ejUnmarshaler interface {
UnmarshalEasyJSON(w *jlexer.Lexer)
}
// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaller
// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaler
// so it takes the fastest option available.
func WriteJSON(data interface{}) ([]byte, error) {
if d, ok := data.(ejMarshaler); ok {
@ -65,8 +65,8 @@ func WriteJSON(data interface{}) ([]byte, error) {
return json.Marshal(data)
}
// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaller
// so it takes the fastes option available
// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaler
// so it takes the fastest option available
func ReadJSON(data []byte, value interface{}) error {
trimmedData := bytes.Trim(data, "\x00")
if d, ok := value.(ejUnmarshaler); ok {
@ -189,7 +189,7 @@ func FromDynamicJSON(data, target interface{}) error {
return json.Unmarshal(b, target)
}
// NameProvider represents an object capabale of translating from go property names
// NameProvider represents an object capable of translating from go property names
// to json property names
// This type is thread-safe.
type NameProvider struct {

View File

@ -270,16 +270,25 @@ func (w *Writer) Bool(v bool) {
const chars = "0123456789abcdef"
func isNotEscapedSingleChar(c byte, escapeHTML bool) bool {
// Note: might make sense to use a table if there are more chars to escape. With 4 chars
// it benchmarks the same.
if escapeHTML {
return c != '<' && c != '>' && c != '&' && c != '\\' && c != '"' && c >= 0x20 && c < utf8.RuneSelf
} else {
return c != '\\' && c != '"' && c >= 0x20 && c < utf8.RuneSelf
func getTable(falseValues ...int) [128]bool {
table := [128]bool{}
for i := 0; i < 128; i++ {
table[i] = true
}
for _, v := range falseValues {
table[v] = false
}
return table
}
var (
htmlEscapeTable = getTable(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, '"', '&', '<', '>', '\\')
htmlNoEscapeTable = getTable(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, '"', '\\')
)
func (w *Writer) String(s string) {
w.Buffer.AppendByte('"')
@ -288,15 +297,23 @@ func (w *Writer) String(s string) {
p := 0 // last non-escape symbol
var escapeTable [128]bool
if w.NoEscapeHTML {
escapeTable = htmlNoEscapeTable
} else {
escapeTable = htmlEscapeTable
}
for i := 0; i < len(s); {
c := s[i]
if isNotEscapedSingleChar(c, !w.NoEscapeHTML) {
// single-width character, no escaping is required
i++
continue
} else if c < utf8.RuneSelf {
// single-with character, need to escape
if c < utf8.RuneSelf {
if escapeTable[c] {
// single-width character, no escaping is required
i++
continue
}
w.Buffer.AppendString(s[p:i])
switch c {
case '\t':

View File

@ -2,7 +2,6 @@ language: go
sudo: false
go:
- 1.10.x
- 1.11.x
- 1.12.x

View File

@ -9,6 +9,7 @@ GOTEST:=$(GOCMD) test
GOGET:=$(GOCMD) get
GOLIST:=$(GOCMD) list
GOVET:=$(GOCMD) vet
GOPATH:=$(shell $(GOCMD) env GOPATH)
u := $(if $(update),-u)
BINARY_NAME:=swag
@ -53,16 +54,20 @@ clean:
.PHONY: deps
deps:
$(GOGET) ${u} -d
$(GOGET) github.com/swaggo/cli
$(GOGET) github.com/ghodss/yaml
$(GOGET) github.com/gin-gonic/gin
$(GOGET) github.com/KyleBanks/depth
$(GOGET) github.com/go-openapi/jsonreference
$(GOGET) github.com/go-openapi/spec
$(GOGET) github.com/stretchr/testify/assert
$(GOGET) github.com/alecthomas/template
$(GOGET) golang.org/x/tools/go/loader
.PHONY: devel-deps
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
golang.org/x/lint/golint
.PHONY: lint
lint: devel-deps

View File

@ -45,7 +45,7 @@ $ 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).
Or download a pre-compiled binary from the [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`).
```sh
@ -71,7 +71,7 @@ OPTIONS:
--generalInfo value, -g value Go file path in which 'swagger general API Info' is written (default: "main.go")
--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")
--output value, -o value Output directory for all 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
```
@ -277,7 +277,7 @@ func (c *Controller) ListAccounts(ctx *gin.Context) {
$ swag init
```
4.Run your app, and browse to http://localhost:8080/swagger/index.html. You will see Swagger 2.0 Api documents as shown below:
4. Run your app, and browse to http://localhost:8080/swagger/index.html. You will see Swagger 2.0 Api documents as shown below:
![swagger_index.html](https://raw.githubusercontent.com/swaggo/swag/master/assets/swagger-image.png)
@ -598,7 +598,7 @@ generated swagger doc as follows:
```go
type Account struct {
ID int `json:"id" extensions:"x-nullable,x-abc=def"` // extensions fields must start with "x-"
ID string `json:"id" extensions:"x-nullable,x-abc=def"` // extensions fields must start with "x-"
}
```

View File

@ -10,13 +10,77 @@ import (
"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"
const (
searchDirFlag = "dir"
generalInfoFlag = "generalInfo"
propertyStrategyFlag = "propertyStrategy"
outputFlag = "output"
parseVendorFlag = "parseVendor"
parseDependencyFlag = "parseDependency"
markdownFilesFlag = "markdownFiles"
generatedTimeFlag = "generatedTime"
)
var initFlags = []cli.Flag{
cli.StringFlag{
Name: generalInfoFlag + ", g",
Value: "main.go",
Usage: "Go file path in which 'swagger general API Info' is written",
},
cli.StringFlag{
Name: searchDirFlag + ", d",
Value: "./",
Usage: "Directory you want to parse",
},
cli.StringFlag{
Name: propertyStrategyFlag + ", p",
Value: "camelcase",
Usage: "Property Naming Strategy like snakecase,camelcase,pascalcase",
},
cli.StringFlag{
Name: outputFlag + ", o",
Value: "./docs",
Usage: "Output directory for all the generated files(swagger.json, swagger.yaml and doc.go)",
},
cli.BoolFlag{
Name: parseVendorFlag,
Usage: "Parse go files in 'vendor' folder, disabled by default",
},
cli.BoolFlag{
Name: parseDependencyFlag,
Usage: "Parse go files in outside dependency folder, disabled by default",
},
cli.StringFlag{
Name: markdownFilesFlag + ", md",
Value: "",
Usage: "Parse folder containing markdown files to use as description, disabled by default",
},
cli.BoolTFlag{
Name: "generatedTime",
Usage: "Generate timestamp at the top of docs.go, true by default",
},
}
func initAction(c *cli.Context) error {
strategy := c.String(propertyStrategyFlag)
switch strategy {
case swag.CamelCase, swag.SnakeCase, swag.PascalCase:
default:
return fmt.Errorf("not supported %s propertyStrategy", strategy)
}
return gen.New().Build(&gen.Config{
SearchDir: c.String(searchDirFlag),
MainAPIFile: c.String(generalInfoFlag),
PropNamingStrategy: strategy,
OutputDir: c.String(outputFlag),
ParseVendor: c.Bool(parseVendorFlag),
ParseDependency: c.Bool(parseDependencyFlag),
MarkdownFilesDir: c.String(markdownFilesFlag),
GeneratedTime: c.BoolT(generatedTimeFlag),
})
}
func main() {
app := cli.NewApp()
@ -27,69 +91,10 @@ func main() {
Name: "init",
Aliases: []string{"i"},
Usage: "Create docs.go",
Action: func(c *cli.Context) error {
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 fmt.Errorf("not supported %s propertyStrategy", strategy)
}
return gen.New().Build(&gen.Config{
SearchDir: searchDir,
MainAPIFile: mainAPIFile,
PropNamingStrategy: strategy,
OutputDir: outputDir,
ParseVendor: parseVendor,
ParseDependency: parseDependency,
MarkdownFilesDir: markdownFilesDir,
})
},
Flags: []cli.Flag{
cli.StringFlag{
Name: "generalInfo, g",
Value: "main.go",
Usage: "Go file path in which 'swagger general API Info' is written",
},
cli.StringFlag{
Name: "dir, d",
Value: "./",
Usage: "Directory you want to parse",
},
cli.StringFlag{
Name: "propertyStrategy, p",
Value: "camelcase",
Usage: "Property Naming Strategy like snakecase,camelcase,pascalcase",
},
cli.StringFlag{
Name: "output, o",
Value: "./docs",
Usage: "Output directory for al the generated files(swagger.json, swagger.yaml and doc.go)",
},
cli.BoolFlag{
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",
},
},
Action: initAction,
Flags: initFlags,
},
}
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)

View File

@ -20,11 +20,19 @@ import (
)
// Gen presents a generate tool for swag.
type Gen struct{}
type Gen struct {
jsonIndent func(data interface{}) ([]byte, error)
jsonToYAML func(data []byte) ([]byte, error)
}
// New creates a new Gen.
func New() *Gen {
return &Gen{}
return &Gen{
jsonIndent: func(data interface{}) ([]byte, error) {
return json.MarshalIndent(data, "", " ")
},
jsonToYAML: yaml.JSONToYAML,
}
}
// Config presents Gen configurations.
@ -32,7 +40,7 @@ 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 all the generated files
OutputDir string
// MainAPIFile the Go file path in which 'swagger general API Info' is written
@ -49,6 +57,9 @@ type Config struct {
// MarkdownFilesDir used to find markdownfiles, which can be used for tag descriptions
MarkdownFilesDir string
// GeneratedTime whether swag should generate the timestamp at the top of docs.go
GeneratedTime bool
}
// Build builds swagger json file for given searchDir and mainAPIFile. Returns json
@ -77,52 +88,53 @@ func (g *Gen) Build(config *Config) error {
return err
}
docs, err := os.Create(path.Join(config.OutputDir, "docs.go"))
docFileName := path.Join(config.OutputDir, "docs.go")
jsonFileName := path.Join(config.OutputDir, "swagger.json")
yamlFileName := path.Join(config.OutputDir, "swagger.yaml")
docs, err := os.Create(docFileName)
if err != nil {
return err
}
defer docs.Close()
swaggerJSON, err := os.Create(path.Join(config.OutputDir, "swagger.json"))
if err != nil {
return err
}
defer swaggerJSON.Close()
if _, err := swaggerJSON.Write(b); err != nil {
return err
}
swaggerYAML, err := os.Create(path.Join(config.OutputDir, "swagger.yaml"))
err = g.writeFile(b, jsonFileName)
if err != nil {
return err
}
defer swaggerYAML.Close()
y, err := yaml.JSONToYAML(b)
y, err := g.jsonToYAML(b)
if err != nil {
return fmt.Errorf("cannot covert json to yaml error: %s", err)
}
if _, err := swaggerYAML.Write(y); err != nil {
return err
}
// Write doc
err = g.writeGoDoc(docs, swagger)
err = g.writeFile(y, yamlFileName)
if err != nil {
return err
}
log.Printf("create docs.go at %+v", docs.Name())
log.Printf("create swagger.json at %+v", swaggerJSON.Name())
log.Printf("create swagger.yaml at %+v", swaggerYAML.Name())
// Write doc
err = g.writeGoDoc(docs, swagger, config)
if err != nil {
return err
}
log.Printf("create docs.go at %+v", docFileName)
log.Printf("create swagger.json at %+v", jsonFileName)
log.Printf("create swagger.yaml at %+v", yamlFileName)
return nil
}
func (g *Gen) jsonIndent(data interface{}) ([]byte, error) {
return json.MarshalIndent(data, "", " ")
func (g *Gen) writeFile(b []byte, file string) error {
f, err := os.Create(file)
if err != nil {
return err
}
defer f.Close()
_, err = f.Write(b)
return err
}
func (g *Gen) formatSource(src []byte) []byte {
@ -133,7 +145,7 @@ func (g *Gen) formatSource(src []byte) []byte {
return code
}
func (g *Gen) writeGoDoc(output io.Writer, swagger *spec.Swagger) error {
func (g *Gen) writeGoDoc(output io.Writer, swagger *spec.Swagger, config *Config) error {
generator, err := template.New("swagger_info").Funcs(template.FuncMap{
"printDoc": func(v string) string {
@ -186,23 +198,25 @@ func (g *Gen) writeGoDoc(output io.Writer, swagger *spec.Swagger) error {
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.Time
GeneratedTime bool
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,
Timestamp: time.Now(),
GeneratedTime: config.GeneratedTime,
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
@ -213,12 +227,11 @@ func (g *Gen) writeGoDoc(output io.Writer, swagger *spec.Swagger) error {
// 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 }}
// This file was generated by swaggo/swag{{ if .GeneratedTime }} at
// {{ .Timestamp }}{{ end }}
package docs

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

@ -4,11 +4,15 @@ require (
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/go-openapi/jsonreference v0.19.0
github.com/go-openapi/spec v0.19.0
github.com/stretchr/testify v1.3.0
github.com/gin-gonic/gin v1.4.0
github.com/go-openapi/jsonreference v0.19.3
github.com/go-openapi/spec v0.19.4
github.com/satori/go.uuid v1.2.0
github.com/stretchr/testify v1.4.0
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/tools v0.0.0-20190611222205-d73e1c7e250b
github.com/urfave/cli v1.22.2
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59
)
go 1.13

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

@ -1,74 +1,127 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
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/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
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/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc=
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/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
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 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=
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.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
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/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
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/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo=
github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
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.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
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.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
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/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
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-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
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/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/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
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/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM=
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
github.com/swaggo/gin-swagger v1.2.0 h1:YskZXEiv51fjOMTsXrOetAjrMDfFaXD79PEoQBOe2W0=
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 h1:jyJKFOSEbdOc2HODrf2qcCkYOdq7zzXqA9bhW5oV4fM=
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 h1:5YV9PsFAN+ndcCtTM7s60no7nY7eTG3LPtxhSwuxzCs=
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=
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
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-20190404232315-eb5bcb51f2a3/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/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae h1:xiXzMMEQdQcric9hXtr1QU98MHunKK7OTtsoU6bYWs4=
golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@ -76,9 +129,14 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
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=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59 h1:QjA/9ArTfVTLfEhClDCG7SGrZkZixxWpwNCDiwJfh88=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/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/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=

View File

@ -144,6 +144,7 @@ func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.F
if strings.HasPrefix(refType, "[]") == true {
objectType = "array"
refType = strings.TrimPrefix(refType, "[]")
refType = TransToValidSchemeType(refType)
} else if IsPrimitiveType(refType) ||
paramType == "formData" && refType == "file" {
objectType = "primitive"
@ -174,32 +175,96 @@ func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.F
},
}
case "object":
return fmt.Errorf("%s is not supported type for %s", refType, paramType)
refType, typeSpec, err := operation.registerSchemaType(refType, astFile)
if err != nil {
return err
}
structType, ok := typeSpec.Type.(*ast.StructType)
if !ok {
return fmt.Errorf("%s is not supported type for %s", refType, paramType)
}
refSplit := strings.Split(refType, ".")
schema, err := operation.parser.parseStruct(refSplit[0], structType.Fields)
if err != nil {
return err
}
if len(schema.Properties) == 0 {
return nil
}
find := func(arr []string, target string) bool {
for _, str := range arr {
if str == target {
return true
}
}
return false
}
for name, prop := range schema.Properties {
if len(prop.Type) == 0 {
continue
}
if prop.Type[0] == "array" &&
prop.Items.Schema != nil &&
len(prop.Items.Schema.Type) > 0 &&
IsSimplePrimitiveType(prop.Items.Schema.Type[0]) {
param = createParameter(paramType, prop.Description, name, prop.Type[0], find(schema.Required, name))
param.SimpleSchema.Type = prop.Type[0]
param.SimpleSchema.Items = &spec.Items{
SimpleSchema: spec.SimpleSchema{
Type: prop.Items.Schema.Type[0],
},
}
} else if IsSimplePrimitiveType(prop.Type[0]) {
param = createParameter(paramType, prop.Description, name, prop.Type[0], find(schema.Required, name))
} else {
Println(fmt.Sprintf("skip field [%s] in %s is not supported type for %s", name, refType, paramType))
continue
}
param.CommonValidations.Maximum = prop.Maximum
param.CommonValidations.Minimum = prop.Minimum
param.CommonValidations.ExclusiveMaximum = prop.ExclusiveMaximum
param.CommonValidations.ExclusiveMinimum = prop.ExclusiveMinimum
param.CommonValidations.MaxLength = prop.MaxLength
param.CommonValidations.MinLength = prop.MinLength
param.CommonValidations.Pattern = prop.Pattern
param.CommonValidations.MaxItems = prop.MaxItems
param.CommonValidations.MinItems = prop.MinItems
param.CommonValidations.UniqueItems = prop.UniqueItems
param.CommonValidations.MultipleOf = prop.MultipleOf
param.CommonValidations.Enum = prop.Enum
operation.Operation.Parameters = append(operation.Operation.Parameters, param)
}
return nil
}
case "body":
switch objectType {
case "primitive":
param.Schema.Type = spec.StringOrArray{refType}
case "array":
param.Schema.Type = spec.StringOrArray{objectType}
param.Schema.Items = &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{},
},
}
// Arrau of Primitive or Object
// Array of Primitive or Object
if IsPrimitiveType(refType) {
param.Schema.Items.Schema.Type = spec.StringOrArray{refType}
} else {
if err := operation.registerSchemaType(refType, astFile); err != nil {
var err error
refType, _, err = operation.registerSchemaType(refType, astFile)
if 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 {
var err error
refType, _, err = operation.registerSchemaType(refType, astFile)
if err != nil {
return err
}
param.Schema.Type = spec.StringOrArray{objectType}
param.Schema.Type = []string{}
param.Schema.Ref = spec.Ref{
Ref: jsonreference.MustCreateRef("#/definitions/" + refType),
}
@ -215,20 +280,23 @@ func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.F
return nil
}
func (operation *Operation) registerSchemaType(schemaType string, astFile *ast.File) error {
refSplit := strings.Split(schemaType, ".")
if len(refSplit) != 2 {
return nil
func (operation *Operation) registerSchemaType(schemaType string, astFile *ast.File) (string, *ast.TypeSpec, error) {
if !strings.ContainsRune(schemaType, '.') {
if astFile == nil {
return schemaType, nil, fmt.Errorf("no package name for type %s", schemaType)
}
schemaType = astFile.Name.String() + "." + schemaType
}
refSplit := strings.Split(schemaType, ".")
pkgName := refSplit[0]
typeName := refSplit[1]
if typeSpec, ok := operation.parser.TypeDefinitions[pkgName][typeName]; ok {
operation.parser.registerTypes[schemaType] = typeSpec
return nil
return schemaType, typeSpec, nil
}
var typeSpec *ast.TypeSpec
if astFile == nil {
return fmt.Errorf("can not register schema type: %q reason: astFile == nil", schemaType)
return schemaType, nil, fmt.Errorf("can not register schema type: %q reason: astFile == nil", schemaType)
}
for _, imp := range astFile.Imports {
if imp.Name != nil && imp.Name.Name == pkgName { // the import had an alias that matched
@ -239,14 +307,14 @@ func (operation *Operation) registerSchemaType(schemaType string, astFile *ast.F
var err error
typeSpec, err = findTypeDef(impPath, typeName)
if err != nil {
return fmt.Errorf("can not find type def: %q error: %s", schemaType, err)
return schemaType, nil, fmt.Errorf("can not find type def: %q error: %s", schemaType, err)
}
break
}
}
if typeSpec == nil {
return fmt.Errorf("can not find schema type: %q", schemaType)
return schemaType, nil, fmt.Errorf("can not find schema type: %q", schemaType)
}
if _, ok := operation.parser.TypeDefinitions[pkgName]; !ok {
@ -255,7 +323,7 @@ func (operation *Operation) registerSchemaType(schemaType string, astFile *ast.F
operation.parser.TypeDefinitions[pkgName][typeName] = typeSpec
operation.parser.registerTypes[schemaType] = typeSpec
return nil
return schemaType, typeSpec, nil
}
var regexAttributes = map[string]*regexp.Regexp{
@ -437,7 +505,7 @@ func parseMimeTypeList(mimeTypeList string, typeList *[]string, format string) e
return nil
}
var routerPattern = regexp.MustCompile(`([\w\.\/\-{}\+]+)[^\[]+\[([^\]]+)`)
var routerPattern = regexp.MustCompile(`^(/[\w\.\/\-{}\+:]*)[[:blank:]]+\[(\w+)]`)
// ParseRouterComment parses comment for gived `router` comment string.
func (operation *Operation) ParseRouterComment(commentLine string) error {
@ -563,14 +631,12 @@ 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
if !IsGolangPrimitiveType(refType) {
if operation.parser != nil { // checking refType has existing in 'TypeDefinitions'
var err error
if refType, _, err = operation.registerSchemaType(refType, astFile); err != nil {
return err
}
}
}

View File

@ -46,6 +46,9 @@ type Parser struct {
// TypeDefinitions is a map that stores [package name][type name][*ast.TypeSpec]
TypeDefinitions map[string]map[string]*ast.TypeSpec
// ImportAliases is map that stores [import name][import package name][*ast.ImportSpec]
ImportAliases map[string]map[string]*ast.ImportSpec
// CustomPrimitiveTypes is a map that stores custom primitive types to actual golang types [type name][string]
CustomPrimitiveTypes map[string]string
@ -85,6 +88,7 @@ func New(options ...func(*Parser)) *Parser {
},
files: make(map[string]*ast.File),
TypeDefinitions: make(map[string]map[string]*ast.TypeSpec),
ImportAliases: make(map[string]map[string]*ast.ImportSpec),
CustomPrimitiveTypes: make(map[string]string),
registerTypes: make(map[string]*ast.TypeSpec),
}
@ -521,6 +525,23 @@ func (parser *Parser) ParseType(astFile *ast.File) {
}
}
}
for _, importSpec := range astFile.Imports {
if importSpec.Name == nil {
continue
}
alias := importSpec.Name.Name
if _, ok := parser.ImportAliases[alias]; !ok {
parser.ImportAliases[alias] = make(map[string]*ast.ImportSpec)
}
importParts := strings.Split(strings.Trim(importSpec.Path.Value, "\""), "/")
importPkgName := importParts[len(importParts)-1]
parser.ImportAliases[alias][importPkgName] = importSpec
}
}
func (parser *Parser) isInStructStack(refTypeName string) bool {
@ -581,7 +602,7 @@ func (parser *Parser) ParseDefinition(pkgName, typeName string, typeSpec *ast.Ty
if err != nil {
return err
}
parser.swagger.Definitions[refTypeName] = schema
parser.swagger.Definitions[refTypeName] = *schema
return nil
}
@ -605,9 +626,7 @@ func (parser *Parser) collectRequiredFields(pkgName string, properties map[strin
tspec := parser.TypeDefinitions[pkgName][tname]
parser.ParseDefinition(pkgName, tname, tspec)
}
if tname != "object" {
requiredFields = append(requiredFields, prop.SchemaProps.Required...)
}
requiredFields = append(requiredFields, prop.SchemaProps.Required...)
properties[k] = prop
}
@ -629,28 +648,40 @@ func fullTypeName(pkgName, typeName string) string {
// parseTypeExpr parses given type expression that corresponds to the type under
// given name and package, and returns swagger schema for it.
func (parser *Parser) parseTypeExpr(pkgName, typeName string, typeExpr ast.Expr) (spec.Schema, error) {
//TODO: return pointer to spec.Schema
func (parser *Parser) parseTypeExpr(pkgName, typeName string, typeExpr ast.Expr) (*spec.Schema, error) {
switch expr := typeExpr.(type) {
// type Foo struct {...}
case *ast.StructType:
refTypeName := fullTypeName(pkgName, typeName)
if schema, isParsed := parser.swagger.Definitions[refTypeName]; isParsed {
return schema, nil
return &schema, nil
}
return parser.parseStruct(pkgName, expr.Fields)
// type Foo Baz
case *ast.Ident:
if IsGolangPrimitiveType(expr.Name) {
return &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: spec.StringOrArray{TransToValidSchemeType(expr.Name)},
},
}, nil
}
refTypeName := fullTypeName(pkgName, expr.Name)
if _, isParsed := parser.swagger.Definitions[refTypeName]; !isParsed {
if typedef, ok := parser.TypeDefinitions[pkgName][expr.Name]; ok {
parser.ParseDefinition(pkgName, expr.Name, typedef)
}
}
return parser.swagger.Definitions[refTypeName], nil
return &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: spec.Ref{
Ref: jsonreference.MustCreateRef("#/definitions/" + refTypeName),
},
},
}, nil
// type Foo *Baz
case *ast.StarExpr:
@ -660,13 +691,13 @@ func (parser *Parser) parseTypeExpr(pkgName, typeName string, typeExpr ast.Expr)
case *ast.ArrayType:
itemSchema, err := parser.parseTypeExpr(pkgName, "", expr.Elt)
if err != nil {
return spec.Schema{}, err
return &spec.Schema{}, err
}
return spec.Schema{
return &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"array"},
Items: &spec.SchemaOrArray{
Schema: &itemSchema,
Schema: itemSchema,
},
},
}, nil
@ -674,28 +705,25 @@ func (parser *Parser) parseTypeExpr(pkgName, typeName string, typeExpr ast.Expr)
// type Foo pkg.Bar
case *ast.SelectorExpr:
if xIdent, ok := expr.X.(*ast.Ident); ok {
pkgName = xIdent.Name
typeName = expr.Sel.Name
refTypeName := fullTypeName(pkgName, typeName)
if _, isParsed := parser.swagger.Definitions[refTypeName]; !isParsed {
typedef := parser.TypeDefinitions[pkgName][typeName]
parser.ParseDefinition(pkgName, typeName, typedef)
}
return parser.swagger.Definitions[refTypeName], nil
return parser.parseTypeExpr(xIdent.Name, expr.Sel.Name, expr.Sel)
}
// type Foo map[string]Bar
case *ast.MapType:
itemSchema, err := parser.parseTypeExpr(pkgName, "", expr.Value)
if err != nil {
return spec.Schema{}, err
var valueSchema spec.SchemaOrBool
if _, ok := expr.Value.(*ast.InterfaceType); ok {
valueSchema.Allows = true
} else {
schema, err := parser.parseTypeExpr(pkgName, "", expr.Value)
if err != nil {
return &spec.Schema{}, err
}
valueSchema.Schema = schema
}
return spec.Schema{
return &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
AdditionalProperties: &spec.SchemaOrBool{
Schema: &itemSchema,
},
Type: []string{"object"},
AdditionalProperties: &valueSchema,
},
}, nil
// ...
@ -703,21 +731,21 @@ func (parser *Parser) parseTypeExpr(pkgName, typeName string, typeExpr ast.Expr)
Printf("Type definition of type '%T' is not supported yet. Using 'object' instead.\n", typeExpr)
}
return spec.Schema{
return &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
},
}, nil
}
func (parser *Parser) parseStruct(pkgName string, fields *ast.FieldList) (spec.Schema, error) {
func (parser *Parser) parseStruct(pkgName string, fields *ast.FieldList) (*spec.Schema, error) {
extraRequired := make([]string, 0)
properties := make(map[string]spec.Schema)
for _, field := range fields.List {
fieldProps, requiredFromAnon, err := parser.parseStructField(pkgName, field)
if err != nil {
return spec.Schema{}, err
return &spec.Schema{}, err
}
extraRequired = append(extraRequired, requiredFromAnon...)
for k, v := range fieldProps {
@ -730,14 +758,11 @@ func (parser *Parser) parseStruct(pkgName string, fields *ast.FieldList) (spec.S
// unset required from properties because we've collected them
for k, prop := range properties {
tname := prop.SchemaProps.Type[0]
if tname != "object" {
prop.SchemaProps.Required = make([]string, 0)
}
prop.SchemaProps.Required = make([]string, 0)
properties[k] = prop
}
return spec.Schema{
return &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"},
Properties: properties,
@ -747,6 +772,7 @@ func (parser *Parser) parseStruct(pkgName string, fields *ast.FieldList) (spec.S
type structField struct {
name string
desc string
schemaType string
arrayType string
formatType string
@ -763,6 +789,34 @@ type structField struct {
extensions map[string]interface{}
}
func (sf *structField) toStandardSchema() *spec.Schema {
required := make([]string, 0)
if sf.isRequired {
required = append(required, sf.name)
}
return &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{sf.schemaType},
Description: sf.desc,
Format: sf.formatType,
Required: required,
Maximum: sf.maximum,
Minimum: sf.minimum,
MaxLength: sf.maxLength,
MinLength: sf.minLength,
Enum: sf.enums,
Default: sf.defaultValue,
},
SwaggerSchemaProps: spec.SwaggerSchemaProps{
Example: sf.exampleValue,
ReadOnly: sf.readOnly,
},
VendorExtensible: spec.VendorExtensible{
Extensions: sf.extensions,
},
}
}
func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[string]spec.Schema, []string, error) {
properties := map[string]spec.Schema{}
@ -796,7 +850,7 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
properties[k] = v
}
case "array":
properties[typeName] = schema
properties[typeName] = *schema
default:
Printf("Can't extract properties from a schema of type '%s'", schemaType)
}
@ -808,30 +862,51 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
structField, err := parser.parseField(field)
if err != nil {
return properties, nil, nil
return properties, nil, err
}
if structField.name == "" {
return properties, nil, nil
}
var desc string
if field.Doc != nil {
desc = strings.TrimSpace(field.Doc.Text())
}
if desc == "" && field.Comment != nil {
desc = strings.TrimSpace(field.Comment.Text())
}
// TODO: find package of schemaType and/or arrayType
if structField.crossPkg != "" {
pkgName = structField.crossPkg
}
fillObject := func(src, dest interface{}) error {
bin, err := json.Marshal(src)
if err != nil {
return err
}
return json.Unmarshal(bin, dest)
}
//for spec.Schema have implemented json.Marshaler, here in another way to convert
fillSchema := func(src, dest *spec.Schema) error {
err = fillObject(&src.SchemaProps, &dest.SchemaProps)
if err != nil {
return err
}
err = fillObject(&src.SwaggerSchemaProps, &dest.SwaggerSchemaProps)
if err != nil {
return err
}
return fillObject(&src.VendorExtensible, &dest.VendorExtensible)
}
if _, ok := parser.TypeDefinitions[pkgName][structField.schemaType]; ok { // user type field
// write definition if not yet present
parser.ParseDefinition(pkgName, structField.schemaType,
parser.TypeDefinitions[pkgName][structField.schemaType])
required := make([]string, 0)
if structField.isRequired {
required = append(required, structField.name)
}
properties[structField.name] = spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{"object"}, // to avoid swagger validation error
Description: desc,
Description: structField.desc,
Required: required,
Ref: spec.Ref{
Ref: jsonreference.MustCreateRef("#/definitions/" + pkgName + "." + structField.schemaType),
},
@ -845,10 +920,15 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
if _, ok := parser.TypeDefinitions[pkgName][structField.arrayType]; ok { // user type in array
parser.ParseDefinition(pkgName, structField.arrayType,
parser.TypeDefinitions[pkgName][structField.arrayType])
required := make([]string, 0)
if structField.isRequired {
required = append(required, structField.name)
}
properties[structField.name] = spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{structField.schemaType},
Description: desc,
Description: structField.desc,
Required: required,
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
@ -881,7 +961,7 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
properties[structField.name] = spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{structField.schemaType},
Description: desc,
Description: structField.desc,
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
@ -895,6 +975,36 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
ReadOnly: structField.readOnly,
},
}
} else {
schema, _ := parser.parseTypeExpr(pkgName, "", astTypeArray.Elt)
properties[structField.name] = spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{structField.schemaType},
Description: structField.desc,
Items: &spec.SchemaOrArray{
Schema: schema,
},
},
SwaggerSchemaProps: spec.SwaggerSchemaProps{
ReadOnly: structField.readOnly,
},
}
}
}
} else if structField.arrayType == "array" {
if astTypeArray, ok := field.Type.(*ast.ArrayType); ok {
schema, _ := parser.parseTypeExpr(pkgName, "", astTypeArray.Elt)
properties[structField.name] = spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{structField.schemaType},
Description: structField.desc,
Items: &spec.SchemaOrArray{
Schema: schema,
},
},
SwaggerSchemaProps: spec.SwaggerSchemaProps{
ReadOnly: structField.readOnly,
},
}
}
} else {
@ -907,7 +1017,7 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
properties[structField.name] = spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{structField.schemaType},
Description: desc,
Description: structField.desc,
Format: structField.formatType,
Required: required,
Items: &spec.SchemaOrArray{
@ -930,47 +1040,36 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
},
}
}
} else if astTypeMap, ok := field.Type.(*ast.MapType); ok { // if map
stdSchema := structField.toStandardSchema()
mapValueSchema, err := parser.parseTypeExpr(pkgName, "", astTypeMap)
if err != nil {
return properties, nil, err
}
stdSchema.Type = mapValueSchema.Type
stdSchema.AdditionalProperties = mapValueSchema.AdditionalProperties
properties[structField.name] = *stdSchema
} else {
required := make([]string, 0)
if structField.isRequired {
required = append(required, structField.name)
}
properties[structField.name] = spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{structField.schemaType},
Description: desc,
Format: structField.formatType,
Required: required,
Maximum: structField.maximum,
Minimum: structField.minimum,
MaxLength: structField.maxLength,
MinLength: structField.minLength,
Enum: structField.enums,
Default: structField.defaultValue,
},
SwaggerSchemaProps: spec.SwaggerSchemaProps{
Example: structField.exampleValue,
ReadOnly: structField.readOnly,
},
VendorExtensible: spec.VendorExtensible{
Extensions: structField.extensions,
},
}
stdSchema := structField.toStandardSchema()
properties[structField.name] = *stdSchema
if nestStruct, ok := field.Type.(*ast.StarExpr); ok {
schema, err := parser.parseTypeExpr(pkgName, structField.schemaType, nestStruct.X)
if err != nil {
return nil, nil, err
if nestStar, ok := field.Type.(*ast.StarExpr); ok {
if !IsGolangPrimitiveType(structField.schemaType) {
schema, err := parser.parseTypeExpr(pkgName, structField.schemaType, nestStar.X)
if err != nil {
return properties, nil, err
}
if len(schema.SchemaProps.Type) > 0 {
err = fillSchema(schema, stdSchema)
if err != nil {
return properties, nil, err
}
properties[structField.name] = *stdSchema
return properties, nil, nil
}
}
if len(schema.SchemaProps.Type) > 0 {
properties[structField.name] = schema
return properties, nil, nil
}
}
nestStruct, ok := field.Type.(*ast.StructType)
if ok {
} else if nestStruct, ok := field.Type.(*ast.StructType); ok {
props := map[string]spec.Schema{}
nestRequired := make([]string, 0)
for _, v := range nestStruct.Fields.List {
@ -986,26 +1085,9 @@ func (parser *Parser) parseStructField(pkgName string, field *ast.Field) (map[st
props[k] = v
}
}
properties[structField.name] = spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{structField.schemaType},
Description: desc,
Format: structField.formatType,
Properties: props,
Required: nestRequired,
Maximum: structField.maximum,
Minimum: structField.minimum,
MaxLength: structField.maxLength,
MinLength: structField.minLength,
Enum: structField.enums,
Default: structField.defaultValue,
},
SwaggerSchemaProps: spec.SwaggerSchemaProps{
Example: structField.exampleValue,
ReadOnly: structField.readOnly,
},
}
stdSchema.Properties = props
stdSchema.Required = nestRequired
properties[structField.name] = *stdSchema
}
}
return properties, nil, nil
@ -1069,6 +1151,13 @@ func (parser *Parser) parseField(field *ast.Field) (*structField, error) {
structField.name = toLowerCamelCase(structField.name)
}
if field.Doc != nil {
structField.desc = strings.TrimSpace(field.Doc.Text())
}
if structField.desc == "" && field.Comment != nil {
structField.desc = strings.TrimSpace(field.Comment.Text())
}
if field.Tag == nil {
return structField, nil
}
@ -1098,6 +1187,9 @@ func (parser *Parser) parseField(field *ast.Field) (*structField, error) {
if len(parts) >= 2 {
if newSchemaType == "array" {
newArrayType = parts[1]
if err := CheckSchemaType(newArrayType); err != nil {
return nil, err
}
} else if newSchemaType == "primitive" {
newSchemaType = parts[1]
newArrayType = parts[1]
@ -1107,9 +1199,7 @@ func (parser *Parser) parseField(field *ast.Field) (*structField, error) {
if err := CheckSchemaType(newSchemaType); err != nil {
return nil, err
}
if err := CheckSchemaType(newArrayType); err != nil {
return nil, err
}
structField.schemaType = newSchemaType
structField.arrayType = newArrayType
}

View File

@ -60,6 +60,19 @@ func parseFieldSelectorExpr(astTypeSelectorExpr *ast.SelectorExpr, parser *Parse
parser.ParseDefinition(pkgName.Name, astTypeSelectorExpr.Sel.Name, typeDefinitions)
return propertyNewFunc(astTypeSelectorExpr.Sel.Name, pkgName.Name)
}
if aliasedNames, ok := parser.ImportAliases[pkgName.Name]; ok {
for aliasedName := range aliasedNames {
if typeDefinitions, ok := parser.TypeDefinitions[aliasedName][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(aliasedName, astTypeSelectorExpr.Sel.Name, typeDefinitions)
return propertyNewFunc(astTypeSelectorExpr.Sel.Name, aliasedName)
}
}
}
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[astTypeSelectorExpr.Sel.Name]; isCustomType {
return propertyName{SchemaType: actualPrimitiveType, ArrayType: actualPrimitiveType}
}
@ -91,10 +104,7 @@ func getPropertyName(expr ast.Expr, parser *Parser) (propertyName, error) {
}
if astTypeArray, ok := expr.(*ast.ArrayType); ok { // if array
if _, ok := astTypeArray.Elt.(*ast.StructType); ok {
return propertyName{SchemaType: "array", ArrayType: "object"}, nil
}
return getArrayPropertyName(astTypeArray, parser), nil
return getArrayPropertyName(astTypeArray.Elt, parser), nil
}
if _, ok := expr.(*ast.MapType); ok { // if map
@ -111,22 +121,27 @@ func getPropertyName(expr ast.Expr, parser *Parser) (propertyName, error) {
return propertyName{}, errors.New("not supported" + fmt.Sprint(expr))
}
func getArrayPropertyName(astTypeArray *ast.ArrayType, parser *Parser) propertyName {
if astTypeArrayExpr, ok := astTypeArray.Elt.(*ast.SelectorExpr); ok {
return parseFieldSelectorExpr(astTypeArrayExpr, parser, newArrayProperty)
}
if astTypeArrayExpr, ok := astTypeArray.Elt.(*ast.StarExpr); ok {
if astTypeArraySel, ok := astTypeArrayExpr.X.(*ast.SelectorExpr); ok {
return parseFieldSelectorExpr(astTypeArraySel, parser, newArrayProperty)
func getArrayPropertyName(astTypeArrayElt ast.Expr, parser *Parser) propertyName {
switch elt := astTypeArrayElt.(type) {
case *ast.StructType, *ast.MapType, *ast.InterfaceType:
return propertyName{SchemaType: "array", ArrayType: "object"}
case *ast.ArrayType:
return propertyName{SchemaType: "array", ArrayType: "array"}
case *ast.StarExpr:
return getArrayPropertyName(elt.X, parser)
case *ast.SelectorExpr:
return parseFieldSelectorExpr(elt, parser, newArrayProperty)
case *ast.Ident:
name := TransToValidSchemeType(elt.Name)
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[name]; isCustomType {
name = actualPrimitiveType
}
if astTypeArrayIdent, ok := astTypeArrayExpr.X.(*ast.Ident); ok {
name := TransToValidSchemeType(astTypeArrayIdent.Name)
return propertyName{SchemaType: "array", ArrayType: name}
return propertyName{SchemaType: "array", ArrayType: name}
default:
name := TransToValidSchemeType(fmt.Sprintf("%s", astTypeArrayElt))
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[name]; isCustomType {
name = actualPrimitiveType
}
return propertyName{SchemaType: "array", ArrayType: name}
}
itemTypeName := TransToValidSchemeType(fmt.Sprintf("%s", astTypeArray.Elt))
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[itemTypeName]; isCustomType {
itemTypeName = actualPrimitiveType
}
return propertyName{SchemaType: "array", ArrayType: itemTypeName}
}

View File

@ -10,6 +10,16 @@ func CheckSchemaType(typeName string) error {
return nil
}
// IsSimplePrimitiveType determine whether the type name is a simple primitive type
func IsSimplePrimitiveType(typeName string) bool {
switch typeName {
case "string", "number", "integer", "boolean":
return true
default:
return false
}
}
// IsPrimitiveType determine whether the type name is a primitive type
func IsPrimitiveType(typeName string) bool {
switch typeName {

View File

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

8
vendor/modules.txt vendored
View File

@ -56,9 +56,9 @@ github.com/ghodss/yaml
github.com/go-openapi/jsonpointer
# github.com/go-openapi/jsonreference v0.19.3
github.com/go-openapi/jsonreference
# github.com/go-openapi/spec v0.19.4
# github.com/go-openapi/spec v0.19.7
github.com/go-openapi/spec
# github.com/go-openapi/swag v0.19.5
# github.com/go-openapi/swag v0.19.8
github.com/go-openapi/swag
# github.com/go-redis/redis/v7 v7.2.0
github.com/go-redis/redis/v7
@ -114,7 +114,7 @@ github.com/lib/pq/oid
github.com/lib/pq/scram
# github.com/magiconair/properties v1.8.1
github.com/magiconair/properties
# github.com/mailru/easyjson v0.7.0
# github.com/mailru/easyjson v0.7.1
github.com/mailru/easyjson/buffer
github.com/mailru/easyjson/jlexer
github.com/mailru/easyjson/jwriter
@ -192,7 +192,7 @@ github.com/spf13/viper
github.com/stretchr/testify/assert
# github.com/subosito/gotenv v1.2.0
github.com/subosito/gotenv
# github.com/swaggo/swag v1.6.3
# github.com/swaggo/swag v1.6.5
github.com/swaggo/swag
github.com/swaggo/swag/cmd/swag
github.com/swaggo/swag/gen