From 580a4cac58ee3c17503df5c9df5e06ac84132206 Mon Sep 17 00:00:00 2001 From: Andres Martinez Gotor Date: Mon, 23 Oct 2023 10:44:38 +0200 Subject: [PATCH] Chore: Makefile / Magefile task to build plugins (#76763) --- .github/CODEOWNERS | 1 + Makefile | 16 ++++++ pkg/tsdb/Magefile.go | 119 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 pkg/tsdb/Magefile.go diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a2dd9ff2b5a..e78609faf98 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -293,6 +293,7 @@ /pkg/services/pluginsintegration/ @grafana/plugins-platform-backend /pkg/plugins/pfs/ @grafana/plugins-platform-backend @grafana/grafana-as-code /pkg/tsdb/grafana-testdata-datasource/ @grafana/plugins-platform-backend +/pkg/tsdb/Magefile.go @grafana/plugins-platform-backend /pkg/services/pluginsintegration/pluginsettings/ @grafana/plugins-platform-backend # Backend code docs diff --git a/Makefile b/Makefile index 114f0e5c29c..d26b3b4a1a2 100644 --- a/Makefile +++ b/Makefile @@ -141,6 +141,22 @@ build-js: ## Build frontend assets. yarn run build yarn run plugins:build-bundled +build-plugins-go: ## Build decoupled plugins + @echo "build plugins" + @cd pkg/tsdb; \ + mage -v + +PLUGIN_ID ?= + +build-plugin-go: ## Build decoupled plugins + @echo "build plugin $(PLUGIN_ID)" + @cd pkg/tsdb; \ + if [ -z "$(PLUGIN_ID)" ]; then \ + echo "PLUGIN_ID is not set"; \ + exit 1; \ + fi; \ + mage -v buildplugin $(PLUGIN_ID) + build: build-go build-js ## Build backend and frontend. run: $(BRA) ## Build and run web server on filesystem changes. diff --git a/pkg/tsdb/Magefile.go b/pkg/tsdb/Magefile.go new file mode 100644 index 00000000000..89b37228260 --- /dev/null +++ b/pkg/tsdb/Magefile.go @@ -0,0 +1,119 @@ +//go:build mage + +package main + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + build "github.com/grafana/grafana-plugin-sdk-go/build" +) + +func find(dir string, name string) ([]string, error) { + files := []string{} + err := filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { + if err != nil { + return err + } + if filepath.Base(path) == name { + files = append(files, path) + } + return nil + }) + + return files, err +} + +func findPluginJSONDir(pluginDir string) (string, error) { + pluginJSONMatches, err := find(filepath.Join("../../public/app/plugins/datasource", pluginDir), "plugin.json") + if err != nil { + return "", err + } + if len(pluginJSONMatches) == 0 { + return "", fmt.Errorf("Could not find plugin.json") + } + pluginJSONPath := "" + for _, pluginJSONMatch := range pluginJSONMatches { + // Ignore dist folder + if filepath.Base(filepath.Dir(pluginJSONMatch)) != "dist" { + pluginJSONPath = pluginJSONMatch + } + } + pluginJSONPath, err = filepath.Abs(pluginJSONPath) + if err != nil { + return "", err + } + return filepath.Dir(pluginJSONPath), nil +} + +func findRootDir(pluginDir string) (string, error) { + matches, err := find(pluginDir, "main.go") + if err != nil { + return "", err + } + if len(matches) == 0 { + return "", fmt.Errorf("Could not find main.go") + } + absolutePath, err := filepath.Abs(matches[0]) + if err != nil { + return "", err + } + return filepath.Dir(absolutePath), nil +} + +func buildPlugin(rootDir, pluginJSONDir string) { + distDir := filepath.Join(pluginJSONDir, "dist") + + configCallback := func(cfg build.Config) (build.Config, error) { + cfg.OutputBinaryPath = distDir + cfg.PluginJSONPath = pluginJSONDir + cfg.RootPackagePath = rootDir + return cfg, nil + } + build.SetBeforeBuildCallback(configCallback) + build.BuildAll() +} + +func BuildPlugin(pluginDir string) error { + rootDir, err := findRootDir(pluginDir) + if err != nil { + return err + } + pluginJSONDir, err := findPluginJSONDir(pluginDir) + if err != nil { + return err + } + buildPlugin(rootDir, pluginJSONDir) + return nil +} + +func BuildAllPlugins() error { + // Plugins need to have a main.go file + matches, err := find(".", "main.go") + if err != nil { + return err + } + for _, match := range matches { + // Get the directory name of the plugin + parts := strings.Split(filepath.ToSlash(match), "/") + if len(parts) == 0 { + continue + } + pluginDir := parts[0] + rootDir, err := findRootDir(pluginDir) + if err != nil { + return err + } + pluginJSONDir, err := findPluginJSONDir(pluginDir) + if err != nil { + return err + } + buildPlugin(rootDir, pluginJSONDir) + } + return nil +} + +// Default configures the default target. +var Default = BuildAllPlugins