|
|
@ -20,9 +20,11 @@ import (
|
|
|
|
"io/ioutil"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"path/filepath"
|
|
|
|
|
|
|
|
"regexp"
|
|
|
|
"runtime"
|
|
|
|
"runtime"
|
|
|
|
"strings"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"sigs.k8s.io/yaml"
|
|
|
|
"sigs.k8s.io/yaml"
|
|
|
|
|
|
|
|
|
|
|
|
"helm.sh/helm/v3/pkg/cli"
|
|
|
|
"helm.sh/helm/v3/pkg/cli"
|
|
|
@ -157,18 +159,51 @@ func (p *Plugin) PrepareCommand(extraArgs []string) (string, []string, error) {
|
|
|
|
return main, baseArgs, nil
|
|
|
|
return main, baseArgs, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// validPluginName is a regular expression that validates plugin names.
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// Plugin names can only contain the ASCII characters a-z, A-Z, 0-9, _ and -.
|
|
|
|
|
|
|
|
var validPluginName = regexp.MustCompile("^[A-Za-z0-9_-]+$")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// validatePluginData validates a plugin's YAML data.
|
|
|
|
|
|
|
|
func validatePluginData(plug *Plugin, filepath string) error {
|
|
|
|
|
|
|
|
if !validPluginName.MatchString(plug.Metadata.Name) {
|
|
|
|
|
|
|
|
return fmt.Errorf("invalid plugin name at %q", filepath)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// We could also validate SemVer, executable, and other fields should we so choose.
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func detectDuplicates(plugs []*Plugin) error {
|
|
|
|
|
|
|
|
names := map[string]string{}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for _, plug := range plugs {
|
|
|
|
|
|
|
|
if oldpath, ok := names[plug.Metadata.Name]; ok {
|
|
|
|
|
|
|
|
return fmt.Errorf(
|
|
|
|
|
|
|
|
"two plugins claim the name %q at %q and %q",
|
|
|
|
|
|
|
|
plug.Metadata.Name,
|
|
|
|
|
|
|
|
oldpath,
|
|
|
|
|
|
|
|
plug.Dir,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
names[plug.Metadata.Name] = plug.Dir
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// LoadDir loads a plugin from the given directory.
|
|
|
|
// LoadDir loads a plugin from the given directory.
|
|
|
|
func LoadDir(dirname string) (*Plugin, error) {
|
|
|
|
func LoadDir(dirname string) (*Plugin, error) {
|
|
|
|
data, err := ioutil.ReadFile(filepath.Join(dirname, PluginFileName))
|
|
|
|
pluginfile := filepath.Join(dirname, PluginFileName)
|
|
|
|
|
|
|
|
data, err := ioutil.ReadFile(pluginfile)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
return nil, errors.Wrapf(err, "failed to read plugin at %q", pluginfile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
plug := &Plugin{Dir: dirname}
|
|
|
|
plug := &Plugin{Dir: dirname}
|
|
|
|
if err := yaml.Unmarshal(data, &plug.Metadata); err != nil {
|
|
|
|
if err := yaml.Unmarshal(data, &plug.Metadata); err != nil {
|
|
|
|
return nil, err
|
|
|
|
return nil, errors.Wrapf(err, "failed to load plugin at %q", pluginfile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return plug, nil
|
|
|
|
return plug, validatePluginData(plug, pluginfile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// LoadAll loads all plugins found beneath the base directory.
|
|
|
|
// LoadAll loads all plugins found beneath the base directory.
|
|
|
@ -180,7 +215,7 @@ func LoadAll(basedir string) ([]*Plugin, error) {
|
|
|
|
scanpath := filepath.Join(basedir, "*", PluginFileName)
|
|
|
|
scanpath := filepath.Join(basedir, "*", PluginFileName)
|
|
|
|
matches, err := filepath.Glob(scanpath)
|
|
|
|
matches, err := filepath.Glob(scanpath)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return plugins, err
|
|
|
|
return plugins, errors.Wrapf(err, "failed to find plugins in %q", scanpath)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if matches == nil {
|
|
|
|
if matches == nil {
|
|
|
@ -195,7 +230,7 @@ func LoadAll(basedir string) ([]*Plugin, error) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
plugins = append(plugins, p)
|
|
|
|
plugins = append(plugins, p)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return plugins, nil
|
|
|
|
return plugins, detectDuplicates(plugins)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FindPlugins returns a list of YAML files that describe plugins.
|
|
|
|
// FindPlugins returns a list of YAML files that describe plugins.
|
|
|
|