From 9943b9a2266d6a2ef46a3731b4d0cfadda30b237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Sat, 9 Jan 2016 08:12:27 +0100 Subject: [PATCH] feat(plugin): more work on plugin schema --- pkg/cmd/web.go | 6 +++--- pkg/plugins/models.go | 36 +++++++++++++++---------------- pkg/plugins/plugins.go | 32 +++++++++++++++++++-------- pkg/plugins/plugins_test.go | 2 +- tests/app-plugin-json/plugin.json | 36 ++++++++++++++----------------- 5 files changed, 60 insertions(+), 52 deletions(-) diff --git a/pkg/cmd/web.go b/pkg/cmd/web.go index 3c433728ba6..ff7f8a053bc 100644 --- a/pkg/cmd/web.go +++ b/pkg/cmd/web.go @@ -30,9 +30,9 @@ func newMacaron() *macaron.Macaron { } for _, route := range plugins.StaticRoutes { - pluginRoute := path.Join("/public/plugins/", route.UrlFragment) - log.Info("Plugin: Adding static route %s -> %s", pluginRoute, route.Dir) - mapStatic(m, route.Dir, "", pluginRoute) + pluginRoute := path.Join("/public/plugins/", route.PluginId) + log.Info("Plugin: Adding static route %s -> %s", pluginRoute, route.Directory) + mapStatic(m, route.Directory, "", pluginRoute) } mapStatic(m, setting.StaticRootPath, "", "public") diff --git a/pkg/plugins/models.go b/pkg/plugins/models.go index 078a63a884f..e60ff558df2 100644 --- a/pkg/plugins/models.go +++ b/pkg/plugins/models.go @@ -5,10 +5,11 @@ import ( ) type PluginCommon struct { - Type string `json:"type"` - Name string `json:"name"` - Id string `json:"id"` - Info PluginInfo `json:"info"` + Type string `json:"type"` + Name string `json:"name"` + Id string `json:"id"` + StaticRoot string `json:"staticRoot"` + Info PluginInfo `json:"info"` } type PluginInfo struct { @@ -38,19 +39,17 @@ type DataSourcePlugin struct { Metrics bool `json:"metrics"` BuiltIn bool `json:"builtIn"` App string `json:"app"` - PublicContent *PublicContent `json:"public"` +} + +type PluginStaticRoute struct { + Directory string + PluginId string } type PanelPlugin struct { PluginCommon - Module string `json:"module"` - PublicContent *PublicContent `json:"public"` - App string `json:"app"` -} - -type PublicContent struct { - UrlFragment string `json:"urlFragment"` - Dir string `json:"dir"` + Module string `json:"module"` + App string `json:"app"` } type ApiPluginRoute struct { @@ -83,12 +82,11 @@ type ApiPlugin struct { type AppPlugin struct { PluginCommon - Enabled bool `json:"enabled"` - Pinned bool `json:"pinned"` - Module string `json:"module"` - Css *AppPluginCss `json:"css"` - Page *AppPluginPage `json:"page"` - PublicContent *PublicContent `json:"public"` + Enabled bool `json:"enabled"` + Pinned bool `json:"pinned"` + Module string `json:"module"` + Css *AppPluginCss `json:"css"` + Page *AppPluginPage `json:"page"` } type EnabledPlugins struct { diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index 8002e505b01..59b0b0db866 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "io" + "net/url" "os" "path" "path/filepath" @@ -21,7 +22,7 @@ var ( DataSources map[string]*DataSourcePlugin Panels map[string]*PanelPlugin ApiPlugins map[string]*ApiPlugin - StaticRoutes []*PublicContent + StaticRoutes []*PluginStaticRoute Apps map[string]*AppPlugin ) @@ -33,7 +34,7 @@ type PluginScanner struct { func Init() error { DataSources = make(map[string]*DataSourcePlugin) ApiPlugins = make(map[string]*ApiPlugin) - StaticRoutes = make([]*PublicContent, 0) + StaticRoutes = make([]*PluginStaticRoute, 0) Panels = make(map[string]*PanelPlugin) Apps = make(map[string]*AppPlugin) @@ -114,11 +115,24 @@ func (scanner *PluginScanner) walker(currentPath string, f os.FileInfo, err erro return nil } -func addPublicContent(public *PublicContent, currentDir string) { - if public != nil { - public.Dir = path.Join(currentDir, public.Dir) - StaticRoutes = append(StaticRoutes, public) +func evalRelativePluginUrlPath(pathStr string, pluginId string) string { + u, _ := url.Parse(pathStr) + if u.IsAbs() { + return pathStr } + return path.Join("public/plugins", pluginId, pathStr) +} + +func addPublicContent(plugin *PluginCommon, currentDir string) { + if plugin.StaticRoot != "" { + StaticRoutes = append(StaticRoutes, &PluginStaticRoute{ + Directory: path.Join(currentDir, plugin.StaticRoot), + PluginId: plugin.Id, + }) + } + + plugin.Info.Logos.Small = evalRelativePluginUrlPath(plugin.Info.Logos.Small, plugin.Id) + plugin.Info.Logos.Large = evalRelativePluginUrlPath(plugin.Info.Logos.Large, plugin.Id) } func interpolatePluginJson(reader io.Reader, pluginCommon *PluginCommon) (io.Reader, error) { @@ -178,7 +192,7 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error { } DataSources[p.Id] = &p - addPublicContent(p.PublicContent, currentDir) + addPublicContent(&p.PluginCommon, currentDir) case "panel": p := PanelPlugin{} @@ -188,7 +202,7 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error { } Panels[p.Id] = &p - addPublicContent(p.PublicContent, currentDir) + addPublicContent(&p.PluginCommon, currentDir) case "api": p := ApiPlugin{} reader.Seek(0, 0) @@ -203,7 +217,7 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error { return err } Apps[p.Id] = &p - addPublicContent(p.PublicContent, currentDir) + addPublicContent(&p.PluginCommon, currentDir) default: return errors.New("Unkown plugin type " + pluginCommon.Type) } diff --git a/pkg/plugins/plugins_test.go b/pkg/plugins/plugins_test.go index 92982d8abe4..dc95d0e2b40 100644 --- a/pkg/plugins/plugins_test.go +++ b/pkg/plugins/plugins_test.go @@ -29,7 +29,7 @@ func TestPluginScans(t *testing.T) { So(err, ShouldBeNil) So(len(Apps), ShouldBeGreaterThan, 0) - So(Apps["app-test"].Info.Logos.Large, ShouldEqual, "public/plugins/app-test/logo_large.png") + So(Apps["app-example"].Info.Logos.Large, ShouldEqual, "public/plugins/app-example/img/logo_large.png") }) } diff --git a/tests/app-plugin-json/plugin.json b/tests/app-plugin-json/plugin.json index 5f48132f4db..986f28c7e99 100644 --- a/tests/app-plugin-json/plugin.json +++ b/tests/app-plugin-json/plugin.json @@ -1,7 +1,19 @@ { - "name": "App Example", - "id": "app-test", "type": "app", + "name": "App Example", + "id": "app-example", + + "staticRoot":" ./public", + "module": "app", + + "pages": [ + {"name": "Example1", "url": "/app-example", "reqRole": "Editor"} + ], + + "css": { + "light": "css/plugin.dark.css", + "dark": "css/plugin.light.css" + }, "info": { "description": "Example Grafana App", @@ -11,8 +23,8 @@ }, "keywords": ["example"], "logos": { - "small": "{{.PluginPublicRoot}}/img/logo_small.png", - "large": "{{.PluginPublicRoot}}/logo_large.png" + "small": "img/logo_small.png", + "large": "img/logo_large.png" }, "links": [ {"name": "Project site", "url": "http://project.com"}, @@ -22,22 +34,6 @@ "updated": "2015-02-10" }, - "css": { - "light": "plugin.dark.css", - "dark": "plugin.light.css" - }, - - "module": "app", - - "pages": [ - {"name": "Example1", "url": "/app-example", "reqRole": "Editor"} - ], - - "public": { - "urlFragment": "app-example", - "path": "./public" - }, - "dependencies": { "grafanaVersion": "2.6.x", "plugins": [