From a74426d631e3311cc3c460ae9917f76f0221f4de Mon Sep 17 00:00:00 2001 From: Piotr Orzechowski Date: Sat, 28 Jul 2018 02:19:01 +0200 Subject: [PATCH] Swagger.v1.json template (#3572) * Turn swagger.v1.json into template * Rename ENABLE_SWAGGER_ENDPOINT option to ENABLE_SWAGGER --- Makefile | 13 +++++++++--- custom/conf/app.ini.sample | 4 ++-- docs/.gitignore | 1 + modules/context/context.go | 2 +- modules/setting/setting.go | 8 +++---- modules/templates/dynamic.go | 16 ++++++++++++-- modules/templates/static.go | 21 ++++++++++++++++--- routers/api/v1/api.go | 4 ++-- routers/api/v1/misc/swagger.go | 2 +- routers/routes/routes.go | 6 +++++- routers/swagger_json.go | 14 +++++++++++++ templates/base/footer.tmpl | 2 +- templates/{swagger.tmpl => swagger/ui.tmpl} | 0 .../swagger/v1_json.tmpl | 2 +- 14 files changed, 74 insertions(+), 21 deletions(-) create mode 100644 routers/swagger_json.go rename templates/{swagger.tmpl => swagger/ui.tmpl} (100%) rename public/swagger.v1.json => templates/swagger/v1_json.tmpl (99%) diff --git a/Makefile b/Makefile index 256e872ad..4eb5873e4 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,10 @@ TAGS ?= 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_DBNAME ?= testgitea TEST_MYSQL_USERNAME ?= root @@ -94,11 +98,12 @@ generate-swagger: @hash swagger > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ $(GO) get -u github.com/go-swagger/go-swagger/cmd/swagger; \ 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 swagger-check: generate-swagger - @diff=$$(git diff public/swagger.v1.json); \ + @diff=$$(git diff '$(SWAGGER_SPEC)'); \ if [ -n "$$diff" ]; then \ echo "Please run 'make generate-swagger' and commit the result:"; \ echo "$${diff}"; \ @@ -110,7 +115,9 @@ swagger-validate: @hash swagger > /dev/null 2>&1; if [ $$? -ne 0 ]; then \ $(GO) get -u github.com/go-swagger/go-swagger/cmd/swagger; \ 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 errcheck: diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index 12e50e8cb..97a0eac02 100644 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -581,8 +581,8 @@ DEFAULT_INTERVAL = 8h MIN_INTERVAL = 10m [api] -; Enables /api/swagger, /api/v1/swagger etc. endpoints. True or false; default is true. -ENABLE_SWAGGER_ENDPOINT = true +; Enables Swagger. True or false; default is true. +ENABLE_SWAGGER = true ; Max number of items in a page MAX_RESPONSE_ITEMS = 50 diff --git a/docs/.gitignore b/docs/.gitignore index a6dcbcccb..55ec469a4 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,2 +1,3 @@ public/ +templates/swagger/v1_json.tmpl themes/ diff --git a/modules/context/context.go b/modules/context/context.go index 7f9193f82..a83187365 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -264,7 +264,7 @@ func Contexter() macaron.Handler { ctx.Data["ShowRegistrationButton"] = setting.Service.ShowRegistrationButton ctx.Data["ShowFooterBranding"] = setting.ShowFooterBranding ctx.Data["ShowFooterVersion"] = setting.ShowFooterVersion - ctx.Data["EnableSwaggerEndpoint"] = setting.API.EnableSwaggerEndpoint + ctx.Data["EnableSwagger"] = setting.API.EnableSwagger ctx.Data["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn c.Map(ctx) diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 396dec254..1b9919404 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -527,11 +527,11 @@ var ( // API settings API = struct { - EnableSwaggerEndpoint bool - MaxResponseItems int + EnableSwagger bool + MaxResponseItems int }{ - EnableSwaggerEndpoint: true, - MaxResponseItems: 50, + EnableSwagger: true, + MaxResponseItems: 50, } U2F = struct { diff --git a/modules/templates/dynamic.go b/modules/templates/dynamic.go index c127b6947..d70a465c1 100644 --- a/modules/templates/dynamic.go +++ b/modules/templates/dynamic.go @@ -22,8 +22,8 @@ var ( templates = template.New("") ) -// Renderer implements the macaron handler for serving the templates. -func Renderer() macaron.Handler { +// HTMLRenderer implements the macaron handler for serving HTML templates. +func HTMLRenderer() macaron.Handler { return macaron.Renderer(macaron.RenderOptions{ Funcs: NewFuncMap(), 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. func Mailer() *template.Template { for _, funcs := range NewFuncMap() { diff --git a/modules/templates/static.go b/modules/templates/static.go index 65b82053f..c16b18cc0 100644 --- a/modules/templates/static.go +++ b/modules/templates/static.go @@ -43,8 +43,7 @@ func (templates templateFileSystem) Get(name string) (io.Reader, error) { return nil, fmt.Errorf("file '%s' not found", name) } -// Renderer implements the macaron handler for serving the templates. -func Renderer() macaron.Handler { +func NewTemplateFileSystem() templateFileSystem { fs := templateFileSystem{} 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{ 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", }) } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 3174e5637..5d47570c5 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -278,13 +278,13 @@ func mustAllowPulls(ctx *context.Context) { func RegisterRoutes(m *macaron.Macaron) { bind := binding.Bind - if setting.API.EnableSwaggerEndpoint { + if setting.API.EnableSwagger { m.Get("/swagger", misc.Swagger) //Render V1 by default } m.Group("/v1", func() { // Miscellaneous - if setting.API.EnableSwaggerEndpoint { + if setting.API.EnableSwagger { m.Get("/swagger", misc.Swagger) } m.Get("/version", misc.Version) diff --git a/routers/api/v1/misc/swagger.go b/routers/api/v1/misc/swagger.go index 0599f8515..e17b77522 100644 --- a/routers/api/v1/misc/swagger.go +++ b/routers/api/v1/misc/swagger.go @@ -10,7 +10,7 @@ import ( ) // tplSwagger swagger page template -const tplSwagger base.TplName = "swagger" +const tplSwagger base.TplName = "swagger/ui" // Swagger render swagger-ui page with v1 json func Swagger(ctx *context.Context) { diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 3eaaff60b..8c196d8bb 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -79,7 +79,7 @@ func NewMacaron() *macaron.Macaron { }, )) - m.Use(templates.Renderer()) + m.Use(templates.HTMLRenderer()) models.InitMailRender(templates.Mailer()) localeNames, err := options.Dir("locale") @@ -755,6 +755,10 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/purge", user.NotificationPurgePost) }, reqSignIn) + if setting.API.EnableSwagger { + m.Get("/swagger.v1.json", templates.JSONRenderer(), routers.SwaggerV1Json) + } + m.Group("/api", func() { apiv1.RegisterRoutes(m) }, ignSignIn) diff --git a/routers/swagger_json.go b/routers/swagger_json.go new file mode 100644 index 000000000..896f1afa2 --- /dev/null +++ b/routers/swagger_json.go @@ -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) +} diff --git a/templates/base/footer.tmpl b/templates/base/footer.tmpl index a23ae5730..26ba3421f 100644 --- a/templates/base/footer.tmpl +++ b/templates/base/footer.tmpl @@ -29,7 +29,7 @@ JavaScript licenses - {{if .EnableSwaggerEndpoint}}API{{end}} + {{if .EnableSwagger}}API{{end}} {{.i18n.Tr "website"}} {{if (or .ShowFooterVersion .PageIsAdmin)}}{{GoVer}}{{end}} diff --git a/templates/swagger.tmpl b/templates/swagger/ui.tmpl similarity index 100% rename from templates/swagger.tmpl rename to templates/swagger/ui.tmpl diff --git a/public/swagger.v1.json b/templates/swagger/v1_json.tmpl similarity index 99% rename from public/swagger.v1.json rename to templates/swagger/v1_json.tmpl index 8ce6488cb..c1026904e 100644 --- a/public/swagger.v1.json +++ b/templates/swagger/v1_json.tmpl @@ -21,7 +21,7 @@ }, "version": "1.1.1" }, - "basePath": "/api/v1", + "basePath": "{{AppSubUrl}}/api/v1", "paths": { "/admin/users": { "post": {