Bumped version of swaggo

This commit is contained in:
konrad 2018-12-01 02:47:54 +01:00
parent 1b24cdf164
commit f778e85d7a
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
49 changed files with 219 additions and 427 deletions

View File

@ -87,7 +87,7 @@ var doc = `{
"description": "The user does not have access to the list",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -139,7 +139,7 @@ var doc = `{
"description": "The user does not have access to the team",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -199,14 +199,14 @@ var doc = `{
"description": "Invalid task object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the list",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -266,14 +266,14 @@ var doc = `{
"description": "Invalid list object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the list",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -320,14 +320,14 @@ var doc = `{
"description": "Invalid list object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the list",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -393,7 +393,7 @@ var doc = `{
"description": "No right to see the list.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -453,21 +453,21 @@ var doc = `{
"description": "Invalid team list object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the list",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "The team does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -533,7 +533,7 @@ var doc = `{
"description": "No right to see the list.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -593,21 +593,21 @@ var doc = `{
"description": "Invalid user list object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the list",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "The user does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -676,14 +676,14 @@ var doc = `{
"description": "The user does not have admin-access to the list",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "Team or list does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -737,14 +737,14 @@ var doc = `{
"description": "The user does not have access to the list",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "Team or list does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -813,14 +813,14 @@ var doc = `{
"description": "The user does not have admin-access to the list",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "User or list does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -874,14 +874,14 @@ var doc = `{
"description": "The user does not have access to the list",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "user or list does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -993,14 +993,14 @@ var doc = `{
"description": "Invalid namespace object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the namespace",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1105,14 +1105,14 @@ var doc = `{
"description": "Invalid namespace object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the namespace",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1164,7 +1164,7 @@ var doc = `{
"description": "The user does not have access to that namespace.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1211,14 +1211,14 @@ var doc = `{
"description": "Invalid namespace object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the namespace",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1345,7 +1345,7 @@ var doc = `{
"description": "No right to see the namespace.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1405,21 +1405,21 @@ var doc = `{
"description": "Invalid team namespace object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The team does not have access to the namespace",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "The team does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1485,7 +1485,7 @@ var doc = `{
"description": "No right to see the namespace.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1545,21 +1545,21 @@ var doc = `{
"description": "Invalid user namespace object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the namespace",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "The user does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1621,14 +1621,14 @@ var doc = `{
"description": "Invalid list object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the list",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1697,14 +1697,14 @@ var doc = `{
"description": "The team does not have admin-access to the namespace",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "Team or namespace does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1758,14 +1758,14 @@ var doc = `{
"description": "The team does not have access to the namespace",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "team or namespace does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1834,14 +1834,14 @@ var doc = `{
"description": "The user does not have admin-access to the namespace",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "User or namespace does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1895,14 +1895,14 @@ var doc = `{
"description": "The user does not have access to the namespace",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "user or namespace does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -1952,7 +1952,7 @@ var doc = `{
"description": "No or invalid user register object provided / User already exists.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2097,14 +2097,14 @@ var doc = `{
"description": "Invalid task object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the task (aka its list)",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2151,14 +2151,14 @@ var doc = `{
"description": "Invalid task ID provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the list",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2263,7 +2263,7 @@ var doc = `{
"description": "Invalid team object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2325,7 +2325,7 @@ var doc = `{
"description": "Invalid team object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2372,7 +2372,7 @@ var doc = `{
"description": "Invalid team object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2434,14 +2434,14 @@ var doc = `{
"description": "Invalid member object provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"403": {
"description": "The user does not have access to the team",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2533,7 +2533,7 @@ var doc = `{
"description": "User does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2583,7 +2583,7 @@ var doc = `{
"description": "Bad token provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2638,14 +2638,14 @@ var doc = `{
"description": "Something's invalid.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"404": {
"description": "User does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2695,7 +2695,7 @@ var doc = `{
"description": "Bad token provided.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2745,7 +2745,7 @@ var doc = `{
"description": "The user does not exist.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2798,7 +2798,7 @@ var doc = `{
"description": "Something's invalid.",
"schema": {
"type": "object",
"$ref": "#/definitions/models.HTTPError"
"$ref": "#/definitions/web.HTTPError"
}
},
"500": {
@ -2838,7 +2838,7 @@ var doc = `{
}
}
},
"models.HTTPError": {
"web.HTTPError": {
"type": "object",
"properties": {
"code": {

2
go.mod
View File

@ -54,7 +54,7 @@ require (
github.com/swaggo/echo-swagger v0.0.0-20180315045949-97f46bb9e5a5
github.com/swaggo/files v0.0.0-20180215091130-49c8a91ea3fa // indirect
github.com/swaggo/gin-swagger v1.0.0 // indirect
github.com/swaggo/swag v1.3.3-0.20181109030545-8f09470d62b2
github.com/swaggo/swag v1.4.0
github.com/urfave/cli v1.20.0 // indirect
github.com/ziutek/mymysql v1.5.4 // indirect
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85

4
go.sum
View File

@ -109,8 +109,8 @@ github.com/swaggo/files v0.0.0-20180215091130-49c8a91ea3fa h1:194s4modF+3X3POBfG
github.com/swaggo/files v0.0.0-20180215091130-49c8a91ea3fa/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
github.com/swaggo/gin-swagger v1.0.0 h1:k6Nn1jV49u+SNIWt7kejQS/iENZKZVMCNQrKOYatNF8=
github.com/swaggo/gin-swagger v1.0.0/go.mod h1:Mt37wE46iUaTAOv+HSnHbJYssKGqbS25X19lNF4YpBo=
github.com/swaggo/swag v1.3.3-0.20181109030545-8f09470d62b2 h1:HMUGTfTJJZ2fRHar570Q2SdUhiCEGwcRRJ2doOOnCJE=
github.com/swaggo/swag v1.3.3-0.20181109030545-8f09470d62b2/go.mod h1:hog2WgeMOrQ/LvQ+o1YGTeT+vWVrbi0SiIslBtxKTyM=
github.com/swaggo/swag v1.4.0 h1:exX5ES4CdJWCCKmVPE+FAIN66cnHeMHU3i2SCMibBZc=
github.com/swaggo/swag v1.4.0/go.mod h1:hog2WgeMOrQ/LvQ+o1YGTeT+vWVrbi0SiIslBtxKTyM=
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/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=

View File

@ -55,7 +55,7 @@ func GetListsByNamespaceID(nID int64) (lists []*List, err error) {
// @Param s query string false "Search lists by title."
// @Security ApiKeyAuth
// @Success 200 {array} models.List "The lists"
// @Failure 403 {object} models.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(search string, a web.Auth, page int) (interface{}, error) {
@ -84,7 +84,7 @@ func (l *List) ReadAll(search string, a web.Auth, page int) (interface{}, error)
// @Security ApiKeyAuth
// @Param id path int true "List ID"
// @Success 200 {object} models.List "The list"
// @Failure 403 {object} models.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) {

View File

@ -59,8 +59,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} models.HTTPError "Invalid list object provided."
// @Failure 403 {object} models.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) {
@ -82,8 +82,8 @@ func (l *List) Update() (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} models.HTTPError "Invalid list object provided."
// @Failure 403 {object} models.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) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Delete implements the delete method of CRUDable
// @Summary Deletes a list
// @Description Delets a list
@ -24,8 +26,8 @@ package models
// @Security ApiKeyAuth
// @Param id path int true "List ID"
// @Success 200 {object} models.Message "The list was successfully deleted."
// @Failure 400 {object} models.HTTPError "Invalid list object provided."
// @Failure 403 {object} models.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

@ -31,8 +31,8 @@ import (
// @Param id path int true "List ID"
// @Param task body models.ListTask true "The task object"
// @Success 200 {object} models.ListTask "The created task object."
// @Failure 400 {object} models.HTTPError "Invalid task object provided."
// @Failure 403 {object} models.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 (i *ListTask) Create(a web.Auth) (err error) {
@ -75,8 +75,8 @@ func (i *ListTask) Create(a web.Auth) (err error) {
// @Param id path int true "Task ID"
// @Param task body models.ListTask true "The task object"
// @Success 200 {object} models.ListTask "The updated task object."
// @Failure 400 {object} models.HTTPError "Invalid task object provided."
// @Failure 403 {object} models.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 (i *ListTask) Update() (err error) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Delete implements the delete method for listTask
// @Summary Delete a task
// @Description Deletes a task from a list. This does not mean "mark it done".
@ -24,8 +26,8 @@ package models
// @Security ApiKeyAuth
// @Param id path int true "Task ID"
// @Success 200 {object} models.Message "The created task object."
// @Failure 400 {object} models.HTTPError "Invalid task ID provided."
// @Failure 403 {object} models.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 (i *ListTask) Delete() (err error) {

View File

@ -28,9 +28,9 @@ import "code.vikunja.io/web"
// @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} models.HTTPError "Invalid user list object provided."
// @Failure 404 {object} models.HTTPError "The user does not exist."
// @Failure 403 {object} models.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 (ul *ListUser) Create(a web.Auth) (err error) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Delete deletes a list <-> user relation
// @Summary Delete a user from a list
// @Description Delets a user from a list. The user won't have access to the list anymore.
@ -25,8 +27,8 @@ package models
// @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} models.HTTPError "The user does not have access to the list"
// @Failure 404 {object} models.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) {

View File

@ -29,7 +29,7 @@ import "code.vikunja.io/web"
// @Param s query string false "Search users by its name."
// @Security ApiKeyAuth
// @Success 200 {array} models.UserWithRight "The users with the right they have."
// @Failure 403 {object} models.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 (ul *ListUser) ReadAll(search string, a web.Auth, page int) (interface{}, error) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Update updates a user <-> list relation
// @Summary Update a user <-> list relation
// @Description Update a user <-> list relation. Mostly used to update the right that user has.
@ -27,8 +29,8 @@ package models
// @Param list body models.ListUser true "The user you want to update."
// @Security ApiKeyAuth
// @Success 200 {object} models.ListUser "The updated user <-> list relation."
// @Failure 403 {object} models.HTTPError "The user does not have admin-access to the list"
// @Failure 404 {object} models.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

@ -76,7 +76,7 @@ func GetNamespaceByID(id int64) (namespace Namespace, err error) {
// @Security ApiKeyAuth
// @Param id path int true "Namespace ID"
// @Success 200 {object} models.Namespace "The Namespace"
// @Failure 403 {object} models.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) {

View File

@ -27,8 +27,8 @@ import "code.vikunja.io/web"
// @Security ApiKeyAuth
// @Param namespace body models.Namespace true "The namespace you want to create."
// @Success 200 {object} models.Namespace "The created namespace."
// @Failure 400 {object} models.HTTPError "Invalid namespace object provided."
// @Failure 403 {object} models.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) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Delete deletes a namespace
// @Summary Deletes a namespace
// @Description Delets a namespace
@ -24,8 +26,8 @@ package models
// @Security ApiKeyAuth
// @Param id path int true "Namespace ID"
// @Success 200 {object} models.Message "The namespace was successfully deleted."
// @Failure 400 {object} models.HTTPError "Invalid namespace object provided."
// @Failure 403 {object} models.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) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Update implements the update method via the interface
// @Summary Updates a namespace
// @Description Updates a namespace.
@ -26,8 +28,8 @@ package models
// @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} models.HTTPError "Invalid namespace object provided."
// @Failure 403 {object} models.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

@ -28,9 +28,9 @@ import "code.vikunja.io/web"
// @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} models.HTTPError "Invalid user namespace object provided."
// @Failure 404 {object} models.HTTPError "The user does not exist."
// @Failure 403 {object} models.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 (un *NamespaceUser) Create(a web.Auth) (err error) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Delete deletes a namespace <-> user relation
// @Summary Delete a user from a namespace
// @Description Delets a user from a namespace. The user won't have access to the namespace anymore.
@ -25,8 +27,8 @@ package models
// @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} models.HTTPError "The user does not have access to the namespace"
// @Failure 404 {object} models.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) {

View File

@ -29,7 +29,7 @@ import "code.vikunja.io/web"
// @Param s query string false "Search users by its name."
// @Security ApiKeyAuth
// @Success 200 {array} models.UserWithRight "The users with the right they have."
// @Failure 403 {object} models.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 (un *NamespaceUser) ReadAll(search string, a web.Auth, page int) (interface{}, error) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Update updates a user <-> namespace relation
// @Summary Update a user <-> namespace relation
// @Description Update a user <-> namespace relation. Mostly used to update the right that user has.
@ -27,8 +29,8 @@ package models
// @Param namespace body models.NamespaceUser true "The user you want to update."
// @Security ApiKeyAuth
// @Success 200 {object} models.NamespaceUser "The updated user <-> namespace relation."
// @Failure 403 {object} models.HTTPError "The user does not have admin-access to the namespace"
// @Failure 404 {object} models.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

@ -28,9 +28,9 @@ import "code.vikunja.io/web"
// @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} models.HTTPError "Invalid team list object provided."
// @Failure 404 {object} models.HTTPError "The team does not exist."
// @Failure 403 {object} models.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) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Delete deletes a team <-> list relation based on the list & team id
// @Summary Delete a team from a list
// @Description Delets a team from a list. The team won't have access to the list anymore.
@ -25,8 +27,8 @@ package models
// @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} models.HTTPError "The user does not have access to the list"
// @Failure 404 {object} models.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) {

View File

@ -29,7 +29,7 @@ import "code.vikunja.io/web"
// @Param s query string false "Search teams by its name."
// @Security ApiKeyAuth
// @Success 200 {array} models.TeamWithRight "The teams with their right."
// @Failure 403 {object} models.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(search string, a web.Auth, page int) (interface{}, error) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Update updates a team <-> list relation
// @Summary Update a team <-> list relation
// @Description Update a team <-> list relation. Mostly used to update the right that team has.
@ -27,8 +29,8 @@ package models
// @Param list body models.TeamList true "The team you want to update."
// @Security ApiKeyAuth
// @Success 200 {object} models.TeamList "The updated team <-> list relation."
// @Failure 403 {object} models.HTTPError "The user does not have admin-access to the list"
// @Failure 404 {object} models.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

@ -28,8 +28,8 @@ import "code.vikunja.io/web"
// @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} models.HTTPError "Invalid member object provided."
// @Failure 403 {object} models.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

@ -28,9 +28,9 @@ import "code.vikunja.io/web"
// @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} models.HTTPError "Invalid team namespace object provided."
// @Failure 404 {object} models.HTTPError "The team does not exist."
// @Failure 403 {object} models.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) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Delete deletes a team <-> namespace relation based on the namespace & team id
// @Summary Delete a team from a namespace
// @Description Delets a team from a namespace. The team won't have access to the namespace anymore.
@ -25,8 +27,8 @@ package models
// @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} models.HTTPError "The team does not have access to the namespace"
// @Failure 404 {object} models.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) {

View File

@ -29,7 +29,7 @@ import "code.vikunja.io/web"
// @Param s query string false "Search teams by its name."
// @Security ApiKeyAuth
// @Success 200 {array} models.TeamWithRight "The teams with the right they have."
// @Failure 403 {object} models.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(search string, a web.Auth, page int) (interface{}, error) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Update updates a team <-> namespace relation
// @Summary Update a team <-> namespace relation
// @Description Update a team <-> namespace relation. Mostly used to update the right that team has.
@ -27,8 +29,8 @@ package models
// @Param namespace body models.TeamNamespace true "The team you want to update."
// @Security ApiKeyAuth
// @Success 200 {object} models.TeamNamespace "The updated team <-> namespace relation."
// @Failure 403 {object} models.HTTPError "The team does not have admin-access to the namespace"
// @Failure 404 {object} models.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 (tl *TeamNamespace) Update() (err error) {

View File

@ -104,7 +104,7 @@ func GetTeamByID(id int64) (team Team, err error) {
// @Security ApiKeyAuth
// @Param id path int true "Team ID"
// @Success 200 {object} models.Team "The team"
// @Failure 403 {object} models.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 /lists/{id} [get]
func (t *Team) ReadOne() (err error) {

View File

@ -27,7 +27,7 @@ import "code.vikunja.io/web"
// @Security ApiKeyAuth
// @Param team body models.Team true "The team you want to create."
// @Success 200 {object} models.Team "The created team."
// @Failure 400 {object} models.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) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Delete deletes a team
// @Summary Deletes a team
// @Description Delets a team. This will also remove the access for all users in that team.
@ -24,7 +26,7 @@ package models
// @Security ApiKeyAuth
// @Param id path int true "Team ID"
// @Success 200 {object} models.Message "The team was successfully deleted."
// @Failure 400 {object} models.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) {

View File

@ -16,6 +16,8 @@
package models
import _ "code.vikunja.io/web" // For swaggerdocs generation
// Update is the handler to create a team
// @Summary Updates a team
// @Description Updates a team.
@ -26,7 +28,7 @@ package models
// @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} models.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

@ -31,7 +31,7 @@ import (
// @Produce json
// @Param credentials body models.APIUserPassword true "The user credentials"
// @Success 200 {object} models.User
// @Failure 400 {object} models.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

@ -31,7 +31,7 @@ import (
// @Produce json
// @Param credentials body models.EmailConfirm true "The token."
// @Success 200 {object} models.Message
// @Failure 412 {object} models.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

@ -32,7 +32,7 @@ import (
// @Param s query string false "Search for a user by its name."
// @Security ApiKeyAuth
// @Success 200 {array} models.User "All (found) users."
// @Failure 400 {object} models.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 {

View File

@ -31,7 +31,7 @@ import (
// @Produce json
// @Param credentials body models.PasswordReset true "The token with the new password."
// @Success 200 {object} models.Message
// @Failure 400 {object} models.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 {
@ -57,7 +57,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} models.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

@ -31,7 +31,7 @@ import (
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} models.User
// @Failure 404 {object} models.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

@ -38,8 +38,8 @@ type UserPassword struct {
// @Param userPassword body v1.UserPassword true "The current and new password."
// @Security ApiKeyAuth
// @Success 200 {object} models.Message
// @Failure 400 {object} models.HTTPError "Something's invalid."
// @Failure 404 {object} models.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

@ -1,6 +1,7 @@
language: go
go:
- 1.8.x
- 1.9.x
- 1.10.x
- 1.11.x
@ -12,6 +13,7 @@ script:
- make lint
- make build
- make test
- go test -race -coverprofile=coverage.txt -covermode=atomic
after_success:
- bash <(curl -s https://codecov.io/bash)

View File

@ -35,7 +35,7 @@ lint:
deps:
$(GOGET) -v ./...
$(GOGET) github.com/stretchr/testify/assert
$(GOGET) golang.org/x/lint/golint
$(GOGET) github.com/golang/lint/golint
$(GOGET) golang.org/x/tools/cmd/goimports
view-covered:

View File

@ -149,46 +149,7 @@ func main() {
r.Run(":8080")
}
//...
```
Additionally some general API info can be set dynamically. The generated code package `docs` exports `SwaggerInfo` variable which we can use to set the title, description, version, host and base path programatically. Example using Gin:
```go
package main
import (
"github.com/gin-gonic/gin"
"github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
"./docs" // docs is generated by Swag CLI, you have to import it.
)
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @termsOfService http://swagger.io/terms/
func main() {
// programatically set swagger info
docs.Title = "Swagger Example API"
docs.Description = "This is a sample server Petstore server."
docs.SwaggerInfo.Version = "1.0"
docs.SwaggerInfo.Host = "petstore.swagger.io"
docs.SwaggerInfo.BasePath = "/v2"
r := gin.New()
// use ginSwagger middleware to serve the API docs
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
r.Run()
}
```
3. Add [API Operation](#api-operation) annotations in `controller` code
@ -304,7 +265,7 @@ OPTIONS:
# General API Info
**Example**
**Example**
[celler/main.go](https://github.com/swaggo/swag/blob/master/example/celler/main.go)
| annotation | description | example |
@ -343,7 +304,7 @@ OPTIONS:
# API Operation
**Example**
**Example**
[celler/controller](https://github.com/swaggo/swag/tree/master/example/celler/controller)
@ -432,16 +393,6 @@ Make it AND condition
// @Param default query string false "string default" default(A)
```
It also works for the struct fields:
```go
type Foo struct {
Bar string `minLength:"4" maxLength:"16"`
Baz int `minimum:"10" maximum:"20" default:"15"`
Qux []string `enums:"foo,bar,baz"`
}
```
### Available
Field Name | Type | Description
@ -511,17 +462,5 @@ type Account struct {
}
```
### Override swagger type of a struct field
```go
type Account struct {
// Override primitive type by simply specifying it via `swaggertype` tag
ID sql.NullInt64 `json:"id" swaggertype:"integer"`
// Array types can be overridden using "array,<prim_type>" format
Coeffs []big.Float `json:"coeffs" swaggertype:"array,number"`
}
```
## About the Project
This project was inspired by [yvasiyarov/swagger](https://github.com/yvasiyarov/swagger) but we simplified the usage and added support a variety of [web frameworks](#supported-web-frameworks).

View File

@ -9,7 +9,6 @@ import (
"time"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
"github.com/swaggo/swag"
)
@ -30,49 +29,33 @@ func (g *Gen) Build(searchDir, mainAPIFile, swaggerConfDir, propNamingStrategy s
p.ParseAPI(searchDir, mainAPIFile)
swagger := p.GetSwagger()
b, err := json.MarshalIndent(swagger, "", " ")
if err != nil {
return err
}
b, _ := json.MarshalIndent(swagger, "", " ")
os.MkdirAll(path.Join(searchDir, "docs"), os.ModePerm)
docs, err := os.Create(path.Join(searchDir, "docs", "docs.go"))
if err != nil {
return err
}
docs, _ := os.Create(path.Join(searchDir, "docs", "docs.go"))
defer docs.Close()
os.Mkdir(swaggerConfDir, os.ModePerm)
swaggerJSON, err := os.Create(path.Join(swaggerConfDir, "swagger.json"))
if err != nil {
return err
}
swaggerJSON, _ := os.Create(path.Join(swaggerConfDir, "swagger.json"))
defer swaggerJSON.Close()
swaggerJSON.Write(b)
swaggerYAML, err := os.Create(path.Join(swaggerConfDir, "swagger.yaml"))
if err != nil {
return err
}
swaggerYAML, _ := os.Create(path.Join(swaggerConfDir, "swagger.yaml"))
defer swaggerYAML.Close()
y, err := yaml.JSONToYAML(b)
if err != nil {
return errors.Wrap(err, "cannot covert json to yaml")
//TODO: using return error instead of panic
log.Fatalf("can't swagger json covert to yaml err: %s", err)
}
swaggerYAML.Write(y)
if err := packageTemplate.Execute(docs, struct {
packageTemplate.Execute(docs, struct {
Timestamp time.Time
Doc string
}{
Timestamp: time.Now(),
Doc: "`" + string(b) + "`",
}); err != nil {
return err
}
})
log.Printf("create docs.go at %+v", docs.Name())
return nil
@ -85,41 +68,16 @@ var packageTemplate = template.Must(template.New("").Parse(`// GENERATED BY THE
package docs
import (
"bytes"
"github.com/alecthomas/template"
"github.com/swaggo/swag"
)
var doc = {{.Doc}}
type swaggerInfo struct {
Version string
Host string
BasePath string
Title string
Description string
}
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo swaggerInfo
type s struct{}
func (s *s) ReadDoc() string {
t, err := template.New("swagger_info").Parse(doc)
if err != nil {
return doc
}
var tpl bytes.Buffer
if err := t.Execute(&tpl, SwaggerInfo); err != nil {
return doc
}
return tpl.String()
return doc
}
func init() {
swag.Register(swag.Name, &s{})
}

View File

@ -50,11 +50,7 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro
lineRemainder := strings.TrimSpace(commentLine[len(attribute):])
switch strings.ToLower(attribute) {
case "@description":
if operation.Description == "" {
operation.Description = lineRemainder
} else {
operation.Description += "<br>" + lineRemainder
}
operation.Description = lineRemainder
case "@summary":
operation.Summary = lineRemainder
case "@id":
@ -390,7 +386,7 @@ func (operation *Operation) ParseProduceComment(commentLine string) error {
// ParseRouterComment parses comment for gived `router` comment string.
func (operation *Operation) ParseRouterComment(commentLine string) error {
re := regexp.MustCompile(`([\w\.\/\-{}\+]+)[^\[]+\[([^\]]+)`)
re := regexp.MustCompile(`([\w\.\/\-{}]+)[^\[]+\[([^\]]+)`)
var matches []string
if matches = re.FindStringSubmatch(commentLine); len(matches) != 3 {

View File

@ -11,14 +11,12 @@ import (
"path"
"path/filepath"
"reflect"
"sort"
"strconv"
"strings"
"unicode"
"github.com/go-openapi/jsonreference"
"github.com/go-openapi/spec"
"github.com/pkg/errors"
)
const (
@ -78,11 +76,9 @@ func New() *Parser {
}
// ParseAPI parses general api info for gived searchDir and mainAPIFile
func (parser *Parser) ParseAPI(searchDir string, mainAPIFile string) error {
func (parser *Parser) ParseAPI(searchDir string, mainAPIFile string) {
log.Println("Generate general API Info")
if err := parser.getAllGoFileInfo(searchDir); err != nil {
return err
}
parser.getAllGoFileInfo(searchDir)
parser.ParseGeneralAPIInfo(path.Join(searchDir, mainAPIFile))
for _, astFile := range parser.files {
@ -94,28 +90,20 @@ func (parser *Parser) ParseAPI(searchDir string, mainAPIFile string) error {
}
parser.ParseDefinitions()
return nil
}
// ParseGeneralAPIInfo parses general api info for gived mainAPIFile path
func (parser *Parser) ParseGeneralAPIInfo(mainAPIFile string) error {
func (parser *Parser) ParseGeneralAPIInfo(mainAPIFile string) {
fileSet := token.NewFileSet()
fileTree, err := goparser.ParseFile(fileSet, mainAPIFile, nil, goparser.ParseComments)
if err != nil {
return errors.Wrap(err, "cannot parse soure files")
log.Panicf("ParseGeneralApiInfo occur error:%+v", err)
}
parser.swagger.Swagger = "2.0"
securityMap := map[string]*spec.SecurityScheme{}
// templated defaults
parser.swagger.Info.Version = "{{.Version}}"
parser.swagger.Info.Title = "{{.Title}}"
parser.swagger.Info.Description = "{{.Description}}"
parser.swagger.Host = "{{.Host}}"
parser.swagger.BasePath = "{{.BasePath}}"
if fileTree.Comments != nil {
for _, comment := range fileTree.Comments {
comments := strings.Split(comment.Text(), "\n")
@ -269,8 +257,6 @@ func (parser *Parser) ParseGeneralAPIInfo(mainAPIFile string) error {
if len(securityMap) > 0 {
parser.swagger.SecurityDefinitions = securityMap
}
return nil
}
func getScopeScheme(scope string) string {
@ -354,7 +340,7 @@ func (parser *Parser) ParseType(astFile *ast.File) {
typeName := fmt.Sprintf("%v", typeSpec.Type)
// check if its a custom primitive type
if IsGolangPrimitiveType(typeName) {
parser.CustomPrimitiveTypes[typeSpec.Name.String()] = TransToValidSchemeType(typeName)
parser.CustomPrimitiveTypes[typeSpec.Name.String()] = typeName
} else {
parser.TypeDefinitions[astFile.Name.String()][typeSpec.Name.String()] = typeSpec
}
@ -378,8 +364,12 @@ var structStacks []string
// isNotRecurringNestStruct check if a structure that is not a not repeating
func isNotRecurringNestStruct(refTypeName string, structStacks []string) bool {
for _, v := range structStacks {
if refTypeName == v {
if len(structStacks) <= 0 {
return true
}
startStruct := structStacks[0]
for _, v := range structStacks[1:] {
if startStruct == v {
return false
}
}
@ -406,19 +396,8 @@ func (parser *Parser) ParseDefinition(pkgName string, typeSpec *ast.TypeSpec, ty
}
structStacks = []string{}
// created sorted list of properties keys so when we iterate over them it's deterministic
ks := make([]string, 0, len(properties))
for k := range properties {
ks = append(ks, k)
}
sort.Strings(ks)
requiredFields := make([]string, 0)
// iterate over keys list instead of map to avoid the random shuffle of the order that go does for maps
for _, k := range ks {
prop := properties[k]
for k, prop := range properties {
// todo find the pkgName of the property type
tname := prop.SchemaProps.Type[0]
if _, ok := parser.TypeDefinitions[pkgName][tname]; ok {
@ -459,11 +438,11 @@ func (parser *Parser) parseTypeSpec(pkgName string, typeSpec *ast.TypeSpec, prop
}
case *ast.ArrayType:
log.Println("ParseDefinitions not supported 'Array' yet.")
log.Panic("ParseDefinitions not supported 'Array' yet.")
case *ast.InterfaceType:
log.Println("ParseDefinitions not supported 'Interface' yet.")
log.Panic("ParseDefinitions not supported 'Interface' yet.")
case *ast.MapType:
log.Println("ParseDefinitions not supported 'Map' yet.")
log.Panic("ParseDefinitions not supported 'Map' yet.")
}
}
@ -475,12 +454,6 @@ type structField struct {
isRequired bool
crossPkg string
exampleValue interface{}
maximum *float64
minimum *float64
maxLength *int64
minLength *int64
enums []interface{}
defaultValue interface{}
}
func (parser *Parser) parseStruct(pkgName string, field *ast.Field) (properties map[string]spec.Schema) {
@ -544,13 +517,7 @@ func (parser *Parser) parseStruct(pkgName string, field *ast.Field) (properties
Items: &spec.SchemaOrArray{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Type: []string{structField.arrayType},
Maximum: structField.maximum,
Minimum: structField.minimum,
MaxLength: structField.maxLength,
MinLength: structField.minLength,
Enum: structField.enums,
Default: structField.defaultValue,
Type: []string{structField.arrayType},
},
},
},
@ -571,12 +538,6 @@ func (parser *Parser) parseStruct(pkgName string, field *ast.Field) (properties
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,
@ -604,12 +565,6 @@ func (parser *Parser) parseStruct(pkgName string, field *ast.Field) (properties
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,
@ -621,18 +576,7 @@ func (parser *Parser) parseStruct(pkgName string, field *ast.Field) (properties
}
func (parser *Parser) parseAnonymousField(pkgName string, field *ast.Field, properties map[string]spec.Schema) {
// check if ast Field is Ident type
astTypeIdent, okTypeIdent := field.Type.(*ast.Ident)
// if ast Field is not Ident type we check if it's StarExpr
// because it might be a pointer to an Ident
if !okTypeIdent {
if astTypeStar, okTypeStar := field.Type.(*ast.StarExpr); okTypeStar {
astTypeIdent, okTypeIdent = astTypeStar.X.(*ast.Ident)
}
}
if okTypeIdent {
if astTypeIdent, ok := field.Type.(*ast.Ident); ok {
findPgkName := pkgName
findBaseTypeName := astTypeIdent.Name
ss := strings.Split(astTypeIdent.Name, ".")
@ -675,8 +619,8 @@ func (parser *Parser) parseField(field *ast.Field) *structField {
return structField
}
// `json:"tag"` -> json:"tag"
structTag := reflect.StructTag(strings.Replace(field.Tag.Value, "`", "", -1))
jsonTag := structTag.Get("json")
structTag := strings.Replace(field.Tag.Value, "`", "", -1)
jsonTag := reflect.StructTag(structTag).Get("json")
// json:"tag,hoge"
if strings.Contains(jsonTag, ",") {
// json:",hoge"
@ -692,28 +636,16 @@ func (parser *Parser) parseField(field *ast.Field) *structField {
structField.name = jsonTag
}
if typeTag := structTag.Get("swaggertype"); typeTag != "" {
parts := strings.Split(typeTag, ",")
if 0 < len(parts) && len(parts) <= 2 {
newSchemaType := parts[0]
newArrayType := structField.arrayType
if len(parts) >= 2 && newSchemaType == "array" {
newArrayType = parts[1]
}
CheckSchemaType(newSchemaType)
CheckSchemaType(newArrayType)
structField.schemaType = newSchemaType
structField.arrayType = newArrayType
}
exampleTag := reflect.StructTag(structTag).Get("example")
if exampleTag != "" {
structField.exampleValue = defineTypeOfExample(structField.schemaType, exampleTag)
}
if exampleTag := structTag.Get("example"); exampleTag != "" {
structField.exampleValue = defineTypeOfExample(structField.schemaType, structField.arrayType, exampleTag)
}
if formatTag := structTag.Get("format"); formatTag != "" {
formatTag := reflect.StructTag(structTag).Get("format")
if formatTag != "" {
structField.formatType = formatTag
}
if bindingTag := structTag.Get("binding"); bindingTag != "" {
bindingTag := reflect.StructTag(structTag).Get("binding")
if bindingTag != "" {
for _, val := range strings.Split(bindingTag, ",") {
if val == "required" {
structField.isRequired = true
@ -721,7 +653,8 @@ func (parser *Parser) parseField(field *ast.Field) *structField {
}
}
}
if validateTag := structTag.Get("validate"); validateTag != "" {
validateTag := reflect.StructTag(structTag).Get("validate")
if validateTag != "" {
for _, val := range strings.Split(validateTag, ",") {
if val == "required" {
structField.isRequired = true
@ -729,60 +662,9 @@ func (parser *Parser) parseField(field *ast.Field) *structField {
}
}
}
if enumsTag := structTag.Get("enums"); enumsTag != "" {
enumType := structField.schemaType
if structField.schemaType == "array" {
enumType = structField.arrayType
}
for _, e := range strings.Split(enumsTag, ",") {
structField.enums = append(structField.enums, defineType(enumType, e))
}
}
if defaultTag := structTag.Get("default"); defaultTag != "" {
structField.defaultValue = defineType(structField.schemaType, defaultTag)
}
if IsNumericType(structField.schemaType) || IsNumericType(structField.arrayType) {
structField.maximum = getFloatTag(structTag, "maximum")
structField.minimum = getFloatTag(structTag, "minimum")
}
if structField.schemaType == "string" || structField.arrayType == "string" {
structField.maxLength = getIntTag(structTag, "maxLength")
structField.minLength = getIntTag(structTag, "minLength")
}
return structField
}
func getFloatTag(structTag reflect.StructTag, tagName string) *float64 {
strValue := structTag.Get(tagName)
if strValue == "" {
return nil
}
value, err := strconv.ParseFloat(strValue, 64)
if err != nil {
panic(fmt.Errorf("can't parse numeric value of %q tag: %v", tagName, err))
}
return &value
}
func getIntTag(structTag reflect.StructTag, tagName string) *int64 {
strValue := structTag.Get(tagName)
if strValue == "" {
return nil
}
value, err := strconv.ParseInt(strValue, 10, 64)
if err != nil {
panic(fmt.Errorf("can't parse numeric value of %q tag: %v", tagName, err))
}
return &value
}
func toSnakeCase(in string) string {
runes := []rune(in)
length := len(runes)
@ -816,7 +698,7 @@ func toLowerCamelCase(in string) string {
}
// defineTypeOfExample example value define the type (object and array unsupported)
func defineTypeOfExample(schemaType, arrayType, exampleValue string) interface{} {
func defineTypeOfExample(schemaType string, exampleValue string) interface{} {
switch schemaType {
case "string":
return exampleValue
@ -839,20 +721,15 @@ func defineTypeOfExample(schemaType, arrayType, exampleValue string) interface{}
}
return v
case "array":
values := strings.Split(exampleValue, ",")
result := make([]interface{}, 0)
for _, value := range values {
result = append(result, defineTypeOfExample(arrayType, "", value))
}
return result
return strings.Split(exampleValue, ",")
default:
panic(fmt.Errorf("%s is unsupported type in example value", schemaType))
}
}
// GetAllGoFileInfo gets all Go source files information for given searchDir.
func (parser *Parser) getAllGoFileInfo(searchDir string) error {
return filepath.Walk(searchDir, parser.visit)
func (parser *Parser) getAllGoFileInfo(searchDir string) {
filepath.Walk(searchDir, parser.visit)
}
func (parser *Parser) visit(path string, f os.FileInfo, err error) error {

View File

@ -55,9 +55,6 @@ func parseFieldSelectorExpr(astTypeSelectorExpr *ast.SelectorExpr, parser *Parse
parser.ParseDefinition(pkgName.Name, typeDefinitions, astTypeSelectorExpr.Sel.Name)
return propertyNewFunc(astTypeSelectorExpr.Sel.Name, pkgName.Name)
}
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[astTypeSelectorExpr.Sel.Name]; isCustomType {
return propertyName{SchemaType: actualPrimitiveType, ArrayType: actualPrimitiveType}
}
}
fmt.Printf("%s is not supported. but it will be set with string temporary. Please report any problems.", astTypeSelectorExpr.Sel.Name)
@ -96,7 +93,7 @@ func getPropertyName(field *ast.Field, parser *Parser) propertyName {
return parseFieldSelectorExpr(astTypeArrayExpr, parser, newArrayProperty)
}
if astTypeArrayIdent, ok := astTypeArray.Elt.(*ast.Ident); ok {
name := TransToValidSchemeType(astTypeArrayIdent.Name)
name := astTypeArrayIdent.Name
return propertyName{SchemaType: "array", ArrayType: name}
}
}
@ -107,11 +104,11 @@ func getPropertyName(field *ast.Field, parser *Parser) propertyName {
}
if astTypeArrayExpr, ok := astTypeArray.Elt.(*ast.StarExpr); ok {
if astTypeArrayIdent, ok := astTypeArrayExpr.X.(*ast.Ident); ok {
name := TransToValidSchemeType(astTypeArrayIdent.Name)
name := astTypeArrayIdent.Name
return propertyName{SchemaType: "array", ArrayType: name}
}
}
itemTypeName := TransToValidSchemeType(fmt.Sprintf("%s", astTypeArray.Elt))
itemTypeName := fmt.Sprintf("%s", astTypeArray.Elt)
if actualPrimitiveType, isCustomType := parser.CustomPrimitiveTypes[itemTypeName]; isCustomType {
itemTypeName = actualPrimitiveType
}

View File

@ -19,11 +19,6 @@ func IsPrimitiveType(typeName string) bool {
}
}
// IsNumericType determines whether the swagger type name is a numeric type
func IsNumericType(typeName string) bool {
return typeName == "integer" || typeName == "number"
}
// TransToValidSchemeType indicates type will transfer golang basic type to swagger supported type.
func TransToValidSchemeType(typeName string) string {
switch typeName {

View File

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

2
vendor/modules.txt vendored
View File

@ -108,7 +108,7 @@ github.com/stretchr/testify/assert
github.com/swaggo/echo-swagger
# github.com/swaggo/files v0.0.0-20180215091130-49c8a91ea3fa
github.com/swaggo/files
# github.com/swaggo/swag v1.3.3-0.20181109030545-8f09470d62b2
# github.com/swaggo/swag v1.4.0
github.com/swaggo/swag/cmd/swag
github.com/swaggo/swag
github.com/swaggo/swag/gen