Skip to content
This repository has been archived by the owner on Jan 20, 2023. It is now read-only.

Commit

Permalink
Check plugins' extensions for conflicts during metadata broker
Browse files Browse the repository at this point in the history
To warn the user of issues with multiple plugins depending on the same
extension, add a step to metadata brokering to detect extensions used by
mutliple plugins and print a warning.

Current approach is very limited, as it depends on extension URLs
matching, so some cases are misse

Signed-off-by: Angel Misevski <amisevsk@redhat.com>
  • Loading branch information
amisevsk committed Feb 11, 2020
1 parent 06a743c commit 512f5e4
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 1 deletion.
8 changes: 7 additions & 1 deletion brokers/metadata/broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
// when downloading metas
const RegistryURLFormat = "%s/%s/meta.yaml"

// Broker is used to process Che plugins
// Broker is used to process Che plugins
type Broker struct {
common.Broker
Expand Down Expand Up @@ -72,6 +71,13 @@ func (b *Broker) Start(pluginFQNs []model.PluginFQN, defaultRegistry string) err
}
b.PrintPlan(pluginMetas)

if collisions := utils.GetExtensionCollisions(pluginMetas); len(collisions) > 0 {
collisionLog := []string{"Warning: some plugins in this workspace have conflicting dependencies:"}
collisionLog = append(collisionLog, utils.ConvertCollisionsToLog(collisions)...)
collisionLog = append(collisionLog, "If you encounter issues with plugins, please disable conflicting plugins above.")
b.PrintInfoBuffer(collisionLog)
}

// Process plugins into ChePlugins
err = b.ProcessPlugins(pluginMetas)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions brokers/testdata/config-plugin-ids.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
{
"id": "ms-kubernetes-tools/vscode-kubernetes-tools/0.1.17"
},
{
"id": "redhat/vscode-openshift-connector/0.1.2"
},
{
"id": "eclipse/che-machine-exec-plugin/0.0.1"
},
Expand Down
52 changes: 52 additions & 0 deletions utils/dependencies.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// Copyright (c) 2020 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//

package utils

import (
"fmt"
"strings"

"github.com/eclipse/che-plugin-broker/model"
)

// GetExtensionCollisions checks a list of plugin metas for extensions shared by
// more than one plugin. Return value is a list of
func GetExtensionCollisions(metas []model.PluginMeta) map[string][]string {
extensions := map[string][]string{}
for _, meta := range metas {
for _, ext := range meta.Spec.Extensions {
extensions[ext] = append(extensions[ext], meta.ID)
}
}
collisions := make(map[string][]string)
for ext, ids := range extensions {
if len(ids) > 1 {
collisions[ext] = ids
}
}
return collisions
}

// ConvertCollisionsToLog converts the ouput of GetExtensionCollisions to a human-readable
// string. Output is a slice of strings, to be joined by newlines
func ConvertCollisionsToLog(collisions map[string][]string) []string {
var output []string
for ext, plugins := range collisions {
output = append(output,
fmt.Sprintf(" Plugins"),
fmt.Sprintf(" { %s }", strings.Join(plugins, ", ")),
fmt.Sprintf(" conflict on extension"),
fmt.Sprintf(" %s", ext))
}
return output
}
60 changes: 60 additions & 0 deletions utils/dependencies_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// Copyright (c) 2020 Red Hat, Inc.
// This program and the accompanying materials are made
// available under the terms of the Eclipse Public License 2.0
// which is available at https://www.eclipse.org/legal/epl-2.0/
//
// SPDX-License-Identifier: EPL-2.0
//
// Contributors:
// Red Hat, Inc. - initial API and implementation
//

package utils

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/eclipse/che-plugin-broker/model"
)

func TestGetExtensionCollisions(t *testing.T) {
metas := []model.PluginMeta{
generateMetaWithExtensions("test/conflict_one", "aaa", "bbb"),
generateMetaWithExtensions("test/no_conflict", "ddd"),
generateMetaWithExtensions("test/conflict_two", "ccc", "bbb"),
}

output := GetExtensionCollisions(metas)
assert.NotEmpty(t, output)
assert.ElementsMatch(t, output["bbb"], []string{"test/conflict_one", "test/conflict_two"})
assert.NotContains(t, output, "aaa")
assert.NotContains(t, output, "ccc")
assert.NotContains(t, output, "ddd")
}

func TestGetExtensionCollisionsMulti(t *testing.T) {
metas := []model.PluginMeta{
generateMetaWithExtensions("one", "aaa", "bbb"),
generateMetaWithExtensions("two", "xxx", "bbb"),
generateMetaWithExtensions("three", "aaa", "yyy"),
}

output := GetExtensionCollisions(metas)
assert.NotEmpty(t, output)
assert.ElementsMatch(t, output["aaa"], []string{"one", "three"})
assert.ElementsMatch(t, output["bbb"], []string{"one", "two"})
assert.NotContains(t, output, "xxx")
assert.NotContains(t, output, "yyy")
}

func generateMetaWithExtensions(id string, exts ...string) model.PluginMeta {
return model.PluginMeta{
ID: id,
Spec: model.PluginMetaSpec{
Extensions: exts,
},
}
}

0 comments on commit 512f5e4

Please sign in to comment.