get.porter.sh/porter@v1.3.0/pkg/plugins/install.go (about) 1 package plugins 2 3 import ( 4 "fmt" 5 "sort" 6 "strings" 7 8 "get.porter.sh/porter/pkg/cnab" 9 "get.porter.sh/porter/pkg/pkgmgmt" 10 "get.porter.sh/porter/pkg/portercontext" 11 ) 12 13 // SchemaTypePlugins is the default schemaType value for InstallPluginsSpec resources 14 const SchemaTypePlugins = "Plugins" 15 16 // InstallPluginsSchemaVersion represents the version associated with the schema 17 // plugins configuration documents. 18 var InstallPluginsSchemaVersion = cnab.SchemaVersion("1.0.0") 19 20 type InstallOptions struct { 21 pkgmgmt.InstallOptions 22 23 File string 24 } 25 26 func (o *InstallOptions) Validate(args []string, cxt *portercontext.Context) error { 27 o.PackageType = "plugin" 28 if o.File != "" { 29 if len(args) > 0 { 30 return fmt.Errorf("plugin name should not be specified when --file is provided") 31 } 32 33 if o.URL != "" { 34 return fmt.Errorf("plugin URL should not be specified when --file is provided") 35 } 36 37 // version should not be set to anything other than the default value 38 if o.Version != "" && o.Version != "latest" { 39 return fmt.Errorf("plugin version %s should not be specified when --file is provided", o.Version) 40 } 41 42 if _, err := cxt.FileSystem.Stat(o.File); err != nil { 43 return fmt.Errorf("unable to access --file %s: %w", o.File, err) 44 } 45 46 return nil 47 } 48 49 return o.InstallOptions.Validate(args) 50 } 51 52 // InstallPluginsSpec represents the user-defined configuration for plugins installation. 53 type InstallPluginsSpec struct { 54 SchemaType string `yaml:"schemaType"` 55 SchemaVersion string `yaml:"schemaVersion"` 56 Plugins InstallPluginsConfig `yaml:"plugins"` 57 } 58 59 func (spec InstallPluginsSpec) Validate() error { 60 if spec.SchemaType != "" && !strings.EqualFold(spec.SchemaType, SchemaTypePlugins) { 61 return fmt.Errorf("invalid schemaType %s, expected %s", spec.SchemaType, SchemaTypePlugins) 62 } 63 64 if InstallPluginsSchemaVersion != cnab.SchemaVersion(spec.SchemaVersion) { 65 if spec.SchemaVersion == "" { 66 spec.SchemaVersion = "(none)" 67 } 68 return fmt.Errorf("invalid schemaVersion provided: %s. This version of Porter is compatible with %s.", spec.SchemaVersion, InstallPluginsSchemaVersion) 69 } 70 return nil 71 } 72 73 // InstallPluginsConfig is the go representation of plugin installation file format. 74 type InstallPluginsConfig map[string]pkgmgmt.InstallOptions 75 76 // InstallPluginsConfigList is a sorted list of InstallationFileOption in alphabetical order. 77 type InstallPluginsConfigList struct { 78 data InstallPluginsConfig 79 keys []string 80 } 81 82 // NewInstallPluginConfigs returns a new instance of InstallPluginConfigs with plugins sorted in alphabetical order 83 // using their names. 84 func NewInstallPluginConfigs(opt InstallPluginsConfig) InstallPluginsConfigList { 85 keys := make([]string, 0, len(opt)) 86 data := make(InstallPluginsConfig, len(opt)) 87 for k, v := range opt { 88 keys = append(keys, k) 89 90 v.Name = k 91 v.PackageType = "plugin" 92 data[k] = v 93 } 94 95 sort.SliceStable(keys, func(i, j int) bool { 96 return keys[i] < keys[j] 97 }) 98 99 return InstallPluginsConfigList{ 100 data: data, 101 keys: keys, 102 } 103 } 104 105 // Values returns InstallOptions list in alphabetical order. 106 func (pc InstallPluginsConfigList) Values() []pkgmgmt.InstallOptions { 107 value := make([]pkgmgmt.InstallOptions, 0, len(pc.keys)) 108 for _, k := range pc.keys { 109 value = append(value, pc.data[k]) 110 } 111 return value 112 }