Swagger.v1.json template (#3572)

* Turn swagger.v1.json into template

* Rename ENABLE_SWAGGER_ENDPOINT option to ENABLE_SWAGGER
This commit is contained in:
Piotr Orzechowski 2018-07-28 02:19:01 +02:00 committed by Lauris BH
parent 412583a3f2
commit a74426d631
14 changed files with 74 additions and 21 deletions

View file

@ -42,6 +42,10 @@ TAGS ?=
TMPDIR := $(shell mktemp -d 2>/dev/null || mktemp -d -t 'gitea-temp') TMPDIR := $(shell mktemp -d 2>/dev/null || mktemp -d -t 'gitea-temp')
SWAGGER_SPEC := templates/swagger/v1_json.tmpl
SWAGGER_SPEC_S_TMPL := s|"basePath":\s*"/api/v1"|"basePath": "{{AppSubUrl}}/api/v1"|g
SWAGGER_SPEC_S_JSON := s|"basePath":\s*"{{AppSubUrl}}/api/v1"|"basePath": "/api/v1"|g
TEST_MYSQL_HOST ?= mysql:3306 TEST_MYSQL_HOST ?= mysql:3306
TEST_MYSQL_DBNAME ?= testgitea TEST_MYSQL_DBNAME ?= testgitea
TEST_MYSQL_USERNAME ?= root TEST_MYSQL_USERNAME ?= root
@ -94,11 +98,12 @@ generate-swagger:
@hash swagger > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash swagger > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/go-swagger/go-swagger/cmd/swagger; \ $(GO) get -u github.com/go-swagger/go-swagger/cmd/swagger; \
fi fi
swagger generate spec -o ./public/swagger.v1.json swagger generate spec -o './$(SWAGGER_SPEC)'
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
.PHONY: swagger-check .PHONY: swagger-check
swagger-check: generate-swagger swagger-check: generate-swagger
@diff=$$(git diff public/swagger.v1.json); \ @diff=$$(git diff '$(SWAGGER_SPEC)'); \
if [ -n "$$diff" ]; then \ if [ -n "$$diff" ]; then \
echo "Please run 'make generate-swagger' and commit the result:"; \ echo "Please run 'make generate-swagger' and commit the result:"; \
echo "$${diff}"; \ echo "$${diff}"; \
@ -110,7 +115,9 @@ swagger-validate:
@hash swagger > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ @hash swagger > /dev/null 2>&1; if [ $$? -ne 0 ]; then \
$(GO) get -u github.com/go-swagger/go-swagger/cmd/swagger; \ $(GO) get -u github.com/go-swagger/go-swagger/cmd/swagger; \
fi fi
swagger validate ./public/swagger.v1.json $(SED_INPLACE) '$(SWAGGER_SPEC_S_JSON)' './$(SWAGGER_SPEC)'
swagger validate './$(SWAGGER_SPEC)'
$(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)'
.PHONY: errcheck .PHONY: errcheck
errcheck: errcheck:

View file

@ -581,8 +581,8 @@ DEFAULT_INTERVAL = 8h
MIN_INTERVAL = 10m MIN_INTERVAL = 10m
[api] [api]
; Enables /api/swagger, /api/v1/swagger etc. endpoints. True or false; default is true. ; Enables Swagger. True or false; default is true.
ENABLE_SWAGGER_ENDPOINT = true ENABLE_SWAGGER = true
; Max number of items in a page ; Max number of items in a page
MAX_RESPONSE_ITEMS = 50 MAX_RESPONSE_ITEMS = 50

1
docs/.gitignore vendored
View file

@ -1,2 +1,3 @@
public/ public/
templates/swagger/v1_json.tmpl
themes/ themes/

View file

@ -264,7 +264,7 @@ func Contexter() macaron.Handler {
ctx.Data["ShowRegistrationButton"] = setting.Service.ShowRegistrationButton ctx.Data["ShowRegistrationButton"] = setting.Service.ShowRegistrationButton
ctx.Data["ShowFooterBranding"] = setting.ShowFooterBranding ctx.Data["ShowFooterBranding"] = setting.ShowFooterBranding
ctx.Data["ShowFooterVersion"] = setting.ShowFooterVersion ctx.Data["ShowFooterVersion"] = setting.ShowFooterVersion
ctx.Data["EnableSwaggerEndpoint"] = setting.API.EnableSwaggerEndpoint ctx.Data["EnableSwagger"] = setting.API.EnableSwagger
ctx.Data["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn ctx.Data["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn
c.Map(ctx) c.Map(ctx)

View file

@ -527,11 +527,11 @@ var (
// API settings // API settings
API = struct { API = struct {
EnableSwaggerEndpoint bool EnableSwagger bool
MaxResponseItems int MaxResponseItems int
}{ }{
EnableSwaggerEndpoint: true, EnableSwagger: true,
MaxResponseItems: 50, MaxResponseItems: 50,
} }
U2F = struct { U2F = struct {

View file

@ -22,8 +22,8 @@ var (
templates = template.New("") templates = template.New("")
) )
// Renderer implements the macaron handler for serving the templates. // HTMLRenderer implements the macaron handler for serving HTML templates.
func Renderer() macaron.Handler { func HTMLRenderer() macaron.Handler {
return macaron.Renderer(macaron.RenderOptions{ return macaron.Renderer(macaron.RenderOptions{
Funcs: NewFuncMap(), Funcs: NewFuncMap(),
Directory: path.Join(setting.StaticRootPath, "templates"), Directory: path.Join(setting.StaticRootPath, "templates"),
@ -33,6 +33,18 @@ func Renderer() macaron.Handler {
}) })
} }
// JSONRenderer implements the macaron handler for serving JSON templates.
func JSONRenderer() macaron.Handler {
return macaron.Renderer(macaron.RenderOptions{
Funcs: NewFuncMap(),
Directory: path.Join(setting.StaticRootPath, "templates"),
AppendDirectories: []string{
path.Join(setting.CustomPath, "templates"),
},
HTMLContentType: "application/json",
})
}
// Mailer provides the templates required for sending notification mails. // Mailer provides the templates required for sending notification mails.
func Mailer() *template.Template { func Mailer() *template.Template {
for _, funcs := range NewFuncMap() { for _, funcs := range NewFuncMap() {

View file

@ -43,8 +43,7 @@ func (templates templateFileSystem) Get(name string) (io.Reader, error) {
return nil, fmt.Errorf("file '%s' not found", name) return nil, fmt.Errorf("file '%s' not found", name)
} }
// Renderer implements the macaron handler for serving the templates. func NewTemplateFileSystem() templateFileSystem {
func Renderer() macaron.Handler {
fs := templateFileSystem{} fs := templateFileSystem{}
fs.files = make([]macaron.TemplateFile, 0, 10) fs.files = make([]macaron.TemplateFile, 0, 10)
@ -110,9 +109,25 @@ func Renderer() macaron.Handler {
} }
} }
return fs
}
var tplFileSys = NewTemplateFileSystem()
// HTMLRenderer implements the macaron handler for serving HTML templates.
func HTMLRenderer() macaron.Handler {
return macaron.Renderer(macaron.RenderOptions{ return macaron.Renderer(macaron.RenderOptions{
Funcs: NewFuncMap(), Funcs: NewFuncMap(),
TemplateFileSystem: fs, TemplateFileSystem: tplFileSys,
})
}
// JSONRenderer implements the macaron handler for serving JSON templates.
func JSONRenderer() macaron.Handler {
return macaron.Renderer(macaron.RenderOptions{
Funcs: NewFuncMap(),
TemplateFileSystem: tplFileSys,
HTMLContentType: "application/json",
}) })
} }

View file

@ -278,13 +278,13 @@ func mustAllowPulls(ctx *context.Context) {
func RegisterRoutes(m *macaron.Macaron) { func RegisterRoutes(m *macaron.Macaron) {
bind := binding.Bind bind := binding.Bind
if setting.API.EnableSwaggerEndpoint { if setting.API.EnableSwagger {
m.Get("/swagger", misc.Swagger) //Render V1 by default m.Get("/swagger", misc.Swagger) //Render V1 by default
} }
m.Group("/v1", func() { m.Group("/v1", func() {
// Miscellaneous // Miscellaneous
if setting.API.EnableSwaggerEndpoint { if setting.API.EnableSwagger {
m.Get("/swagger", misc.Swagger) m.Get("/swagger", misc.Swagger)
} }
m.Get("/version", misc.Version) m.Get("/version", misc.Version)

View file

@ -10,7 +10,7 @@ import (
) )
// tplSwagger swagger page template // tplSwagger swagger page template
const tplSwagger base.TplName = "swagger" const tplSwagger base.TplName = "swagger/ui"
// Swagger render swagger-ui page with v1 json // Swagger render swagger-ui page with v1 json
func Swagger(ctx *context.Context) { func Swagger(ctx *context.Context) {

View file

@ -79,7 +79,7 @@ func NewMacaron() *macaron.Macaron {
}, },
)) ))
m.Use(templates.Renderer()) m.Use(templates.HTMLRenderer())
models.InitMailRender(templates.Mailer()) models.InitMailRender(templates.Mailer())
localeNames, err := options.Dir("locale") localeNames, err := options.Dir("locale")
@ -755,6 +755,10 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/purge", user.NotificationPurgePost) m.Post("/purge", user.NotificationPurgePost)
}, reqSignIn) }, reqSignIn)
if setting.API.EnableSwagger {
m.Get("/swagger.v1.json", templates.JSONRenderer(), routers.SwaggerV1Json)
}
m.Group("/api", func() { m.Group("/api", func() {
apiv1.RegisterRoutes(m) apiv1.RegisterRoutes(m)
}, ignSignIn) }, ignSignIn)

14
routers/swagger_json.go Normal file
View file

@ -0,0 +1,14 @@
package routers
import (
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
)
// tplSwaggerV1Json swagger v1 json template
const tplSwaggerV1Json base.TplName = "swagger/v1_json"
// SwaggerV1Json render swagger v1 json
func SwaggerV1Json(ctx *context.Context) {
ctx.HTML(200, tplSwaggerV1Json)
}

View file

@ -29,7 +29,7 @@
</div> </div>
</div> </div>
<a href="{{AppSubUrl}}/vendor/librejs.html" data-jslicense="1">JavaScript licenses</a> <a href="{{AppSubUrl}}/vendor/librejs.html" data-jslicense="1">JavaScript licenses</a>
{{if .EnableSwaggerEndpoint}}<a href="{{AppSubUrl}}/api/swagger">API</a>{{end}} {{if .EnableSwagger}}<a href="{{AppSubUrl}}/api/swagger">API</a>{{end}}
<a target="_blank" rel="noopener noreferrer" href="https://gitea.io">{{.i18n.Tr "website"}}</a> <a target="_blank" rel="noopener noreferrer" href="https://gitea.io">{{.i18n.Tr "website"}}</a>
{{if (or .ShowFooterVersion .PageIsAdmin)}}<span class="version">{{GoVer}}</span>{{end}} {{if (or .ShowFooterVersion .PageIsAdmin)}}<span class="version">{{GoVer}}</span>{{end}}
</div> </div>

View file

@ -21,7 +21,7 @@
}, },
"version": "1.1.1" "version": "1.1.1"
}, },
"basePath": "/api/v1", "basePath": "{{AppSubUrl}}/api/v1",
"paths": { "paths": {
"/admin/users": { "/admin/users": {
"post": { "post": {