Plugins: Always load decoupled frontend assets from builds (#81873)
* Wip * Wip * Adapt to load external module * build: remove cloudmonitoring from built_in_plugins, clean up webpack output * chore(plugins): remove decoupled plugins from package.json deps * chore(codeowners): update file for nx.json * revert(webpack): put back path in config * build(frontend): use nx to run prod builds of decoupled plugins with yarn build * style(prometheus): run prettier-write to fix tsconfig.json * style(backend): remove unused subFile.isDistDir * revert(locales): remove formatting changes adding new line at end of files * chore(webpack): clean up dev output * build(nx): make grafana an nx project, bump lerna and nx * build(plugin-configs): move cache directory to node_modules * style(datasource-plugins): add eslint ignore for .gen.ts files * chore(codeowners): add frontend-ops as owner of project.json * build(webpack): add getDecoupledPlugins to automatically ignore when watching * ci(drone): skip nx cache when building frontend packages * style(ci): fix missing trailing comma * Revert "style(ci): fix missing trailing comma" This reverts commit7520d41576. * Revert "ci(drone): skip nx cache when building frontend packages" This reverts commit46938883ac. * feat(zipkin): remove from grafana core bundle * chore(npm): bump nx package to latest 18.0.8 * docs(dev-guide): add a note about what yarn start now builds --------- Co-authored-by: Andres Martinez <andres.martinez@grafana.com>
This commit is contained in:
co-authored by
Andres Martinez
parent
75ea33e0cd
commit
6599fa805d
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/config"
|
||||
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
)
|
||||
|
||||
// Service provides methods for constructing asset paths for plugins.
|
||||
@@ -58,9 +57,7 @@ func (s *Service) Base(n PluginInfo) (string, error) {
|
||||
// Module returns the module.js path for the specified plugin.
|
||||
func (s *Service) Module(n PluginInfo) (string, error) {
|
||||
if n.class == plugins.ClassCore {
|
||||
if s.cfg.Features != nil &&
|
||||
s.cfg.Features.IsEnabledGlobally(featuremgmt.FlagExternalCorePlugins) &&
|
||||
filepath.Base(n.dir) == "dist" {
|
||||
if filepath.Base(n.dir) == "dist" {
|
||||
// The core plugin has been built externally, use the module from the dist folder
|
||||
} else {
|
||||
baseDir := getBaseDir(n.dir)
|
||||
|
||||
@@ -59,12 +59,7 @@ func (l *Local) Find(ctx context.Context, src plugins.PluginSource) ([]*plugins.
|
||||
continue
|
||||
}
|
||||
|
||||
followDistFolder := true
|
||||
if src.PluginClass(ctx) == plugins.ClassCore &&
|
||||
!l.features.IsEnabledGlobally(featuremgmt.FlagExternalCorePlugins) {
|
||||
followDistFolder = false
|
||||
}
|
||||
paths, err := l.getAbsPluginJSONPaths(path, followDistFolder)
|
||||
paths, err := l.getAbsPluginJSONPaths(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -167,7 +162,7 @@ func (l *Local) readPluginJSON(pluginJSONPath string) (plugins.JSONData, error)
|
||||
return plugin, nil
|
||||
}
|
||||
|
||||
func (l *Local) getAbsPluginJSONPaths(path string, followDistFolder bool) ([]string, error) {
|
||||
func (l *Local) getAbsPluginJSONPaths(path string) ([]string, error) {
|
||||
var pluginJSONPaths []string
|
||||
|
||||
var err error
|
||||
@@ -176,7 +171,7 @@ func (l *Local) getAbsPluginJSONPaths(path string, followDistFolder bool) ([]str
|
||||
return []string{}, err
|
||||
}
|
||||
|
||||
if err = walk(path, true, true, followDistFolder,
|
||||
if err = walk(path, true, true,
|
||||
func(currentPath string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
|
||||
@@ -313,7 +313,7 @@ func TestFinder_Find(t *testing.T) {
|
||||
func TestFinder_getAbsPluginJSONPaths(t *testing.T) {
|
||||
t.Run("When scanning a folder that doesn't exists shouldn't return an error", func(t *testing.T) {
|
||||
origWalk := walk
|
||||
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error {
|
||||
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop bool, walkFn util.WalkFunc) error {
|
||||
return walkFn(path, nil, os.ErrNotExist)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
@@ -321,14 +321,14 @@ func TestFinder_getAbsPluginJSONPaths(t *testing.T) {
|
||||
})
|
||||
|
||||
finder := NewLocalFinder(false, featuremgmt.WithFeatures())
|
||||
paths, err := finder.getAbsPluginJSONPaths("test", true)
|
||||
paths, err := finder.getAbsPluginJSONPaths("test")
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, paths)
|
||||
})
|
||||
|
||||
t.Run("When scanning a folder that lacks permission shouldn't return an error", func(t *testing.T) {
|
||||
origWalk := walk
|
||||
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error {
|
||||
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop bool, walkFn util.WalkFunc) error {
|
||||
return walkFn(path, nil, os.ErrPermission)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
@@ -336,14 +336,14 @@ func TestFinder_getAbsPluginJSONPaths(t *testing.T) {
|
||||
})
|
||||
|
||||
finder := NewLocalFinder(false, featuremgmt.WithFeatures())
|
||||
paths, err := finder.getAbsPluginJSONPaths("test", true)
|
||||
paths, err := finder.getAbsPluginJSONPaths("test")
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, paths)
|
||||
})
|
||||
|
||||
t.Run("When scanning a folder that returns a non-handled error should return that error", func(t *testing.T) {
|
||||
origWalk := walk
|
||||
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error {
|
||||
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop bool, walkFn util.WalkFunc) error {
|
||||
return walkFn(path, nil, errors.New("random error"))
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
@@ -351,44 +351,10 @@ func TestFinder_getAbsPluginJSONPaths(t *testing.T) {
|
||||
})
|
||||
|
||||
finder := NewLocalFinder(false, featuremgmt.WithFeatures())
|
||||
paths, err := finder.getAbsPluginJSONPaths("test", true)
|
||||
paths, err := finder.getAbsPluginJSONPaths("test")
|
||||
require.Error(t, err)
|
||||
require.Empty(t, paths)
|
||||
})
|
||||
|
||||
t.Run("The followDistFolder state controls whether certain folders are followed", func(t *testing.T) {
|
||||
dir, err := filepath.Abs("../../testdata/pluginRootWithDist")
|
||||
require.NoError(t, err)
|
||||
|
||||
tcs := []struct {
|
||||
name string
|
||||
followDist bool
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "When followDistFolder is enabled, only the nested dist folder will be followed",
|
||||
followDist: true,
|
||||
expected: []string{
|
||||
filepath.Join(dir, "dist/plugin.json"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "When followDistFolder is disabled, no dist folders will be followed",
|
||||
followDist: false,
|
||||
expected: []string{
|
||||
filepath.Join(dir, "datasource/plugin.json"),
|
||||
filepath.Join(dir, "panel/src/plugin.json"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tcs {
|
||||
pluginBundles, err := NewLocalFinder(false, featuremgmt.WithFeatures()).getAbsPluginJSONPaths(dir, tc.followDist)
|
||||
require.NoError(t, err)
|
||||
|
||||
sort.Strings(pluginBundles)
|
||||
require.Equal(t, tc.expected, pluginBundles)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var fsComparer = cmp.Comparer(func(fs1 plugins.FS, fs2 plugins.FS) bool {
|
||||
|
||||
Reference in New Issue
Block a user