소스 검색

feat(plugin): more work on plugin schema

Torkel Ödegaard 10 년 전
부모
커밋
9943b9a226
5개의 변경된 파일60개의 추가작업 그리고 52개의 파일을 삭제
  1. 3 3
      pkg/cmd/web.go
  2. 17 19
      pkg/plugins/models.go
  3. 23 9
      pkg/plugins/plugins.go
  4. 1 1
      pkg/plugins/plugins_test.go
  5. 16 20
      tests/app-plugin-json/plugin.json

+ 3 - 3
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")

+ 17 - 19
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 PanelPlugin struct {
-	PluginCommon
-	Module        string         `json:"module"`
-	PublicContent *PublicContent `json:"public"`
-	App           string         `json:"app"`
+type PluginStaticRoute struct {
+	Directory string
+	PluginId  string
 }
 
-type PublicContent struct {
-	UrlFragment string `json:"urlFragment"`
-	Dir         string `json:"dir"`
+type PanelPlugin struct {
+	PluginCommon
+	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 {

+ 23 - 9
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)
 	}

+ 1 - 1
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")
 	})
 
 }

+ 16 - 20
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": [