(plugin Plugin)
| 185 | } |
| 186 | |
| 187 | func ValidatePlugin(plugin Plugin) error { |
| 188 | required := map[string]string{ |
| 189 | "id": plugin.ID, |
| 190 | "name": plugin.Name, |
| 191 | "description": plugin.Description, |
| 192 | "author": plugin.Author, |
| 193 | } |
| 194 | installType := PluginInstallType(plugin) |
| 195 | if installType == InstallTypeGitHubRelease { |
| 196 | required["repository"] = plugin.Repository |
| 197 | } |
| 198 | for field, value := range required { |
| 199 | if strings.TrimSpace(value) == "" { |
| 200 | return fmt.Errorf("missing required field %s", field) |
| 201 | } |
| 202 | } |
| 203 | if !validPluginID(strings.TrimSpace(plugin.ID)) { |
| 204 | return fmt.Errorf("invalid plugin id %q", plugin.ID) |
| 205 | } |
| 206 | // The version is optional since the latest release is the source of truth; |
| 207 | // when present it is only used as a display fallback and must be valid. |
| 208 | if version := strings.TrimSpace(plugin.Version); version != "" && !validPluginVersion(version) { |
| 209 | return fmt.Errorf("invalid plugin version %q", plugin.Version) |
| 210 | } |
| 211 | switch installType { |
| 212 | case InstallTypeGitHubRelease: |
| 213 | if _, _, errRepository := GitHubRepositoryParts(plugin.Repository); errRepository != nil { |
| 214 | return errRepository |
| 215 | } |
| 216 | case InstallTypeDirect: |
| 217 | if strings.TrimSpace(plugin.Version) == "" { |
| 218 | return fmt.Errorf("missing required field version") |
| 219 | } |
| 220 | if errPlan := ValidateInstallPlan(plugin.Install); errPlan != nil { |
| 221 | return errPlan |
| 222 | } |
| 223 | if errVersions := ValidatePluginVersions(plugin); errVersions != nil { |
| 224 | return errVersions |
| 225 | } |
| 226 | default: |
| 227 | return fmt.Errorf("unsupported install type %q", plugin.Install.Type) |
| 228 | } |
| 229 | return nil |
| 230 | } |
| 231 | |
| 232 | func ValidatePluginVersions(plugin Plugin) error { |
| 233 | if len(plugin.Versions) == 0 { |
no test coverage detected