forked from cloudfoundry/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
plugin_info.go
131 lines (112 loc) · 4.34 KB
/
plugin_info.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package pluginaction
import (
"fmt"
"runtime"
"code.cloudfoundry.org/cli/util/configv3"
"code.cloudfoundry.org/cli/util/generic"
)
type PluginInfo struct {
Name string
Version string
URL string
Checksum string
}
// FetchingPluginInfoFromRepositoryError is returned an error is encountered
// getting plugin info from a repository
type FetchingPluginInfoFromRepositoryError struct {
RepositoryName string
Err error
}
func (e FetchingPluginInfoFromRepositoryError) Error() string {
return fmt.Sprintf("Plugin repository %s returned %s.", e.RepositoryName, e.Err.Error())
}
// NoCompatibleBinaryError is returned when a repository contains a specified
// plugin but not for the specified platform
type NoCompatibleBinaryError struct {
}
func (e NoCompatibleBinaryError) Error() string {
return "Plugin requested has no binary available for your platform."
}
// PluginNotFoundInRepositoryError is an error returned when a plugin is not found.
type PluginNotFoundInRepositoryError struct {
PluginName string
RepositoryName string
}
// Error outputs the plugin not found in repository error message.
func (e PluginNotFoundInRepositoryError) Error() string {
return fmt.Sprintf("Plugin %s not found in repository %s", e.PluginName, e.RepositoryName)
}
// PluginNotFoundInAnyRepositoryError is an error returned when a plugin cannot
// be found in any repositories.
type PluginNotFoundInAnyRepositoryError struct {
PluginName string
}
// Error outputs that the plugin cannot be found in any repositories.
func (e PluginNotFoundInAnyRepositoryError) Error() string {
return fmt.Sprintf("Plugin %s not found in any registered repo", e.PluginName)
}
// GetPluginInfoFromRepositoriesForPlatform returns the newest version of the specified plugin
// and all the repositories that contain that version.
func (actor Actor) GetPluginInfoFromRepositoriesForPlatform(pluginName string, pluginRepos []configv3.PluginRepository, platform string) (PluginInfo, []string, error) {
var reposWithPlugin []string
var newestPluginInfo PluginInfo
var pluginFoundWithIncompatibleBinary bool
for _, repo := range pluginRepos {
pluginInfo, err := actor.getPluginInfoFromRepositoryForPlatform(pluginName, repo, platform)
switch err.(type) {
case PluginNotFoundInRepositoryError:
continue
case NoCompatibleBinaryError:
pluginFoundWithIncompatibleBinary = true
continue
case nil:
if len(reposWithPlugin) == 0 || lessThan(newestPluginInfo.Version, pluginInfo.Version) {
newestPluginInfo = pluginInfo
reposWithPlugin = []string{repo.Name}
} else if pluginInfo.Version == newestPluginInfo.Version {
reposWithPlugin = append(reposWithPlugin, repo.Name)
}
default:
return PluginInfo{}, nil, FetchingPluginInfoFromRepositoryError{
RepositoryName: repo.Name,
Err: err,
}
}
}
if len(reposWithPlugin) == 0 {
if pluginFoundWithIncompatibleBinary {
return PluginInfo{}, nil, NoCompatibleBinaryError{}
} else {
return PluginInfo{}, nil, PluginNotFoundInAnyRepositoryError{PluginName: pluginName}
}
}
return newestPluginInfo, reposWithPlugin, nil
}
// GetPlatformString exists solely for the purposes of mocking it out for command-layers tests.
func (actor Actor) GetPlatformString(runtimeGOOS string, runtimeGOARCH string) string {
return generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH)
}
// getPluginInfoFromRepositoryForPlatform returns the plugin info, if found, from
// the specified repository for the specified platform.
func (actor Actor) getPluginInfoFromRepositoryForPlatform(pluginName string, pluginRepo configv3.PluginRepository, platform string) (PluginInfo, error) {
pluginRepository, err := actor.client.GetPluginRepository(pluginRepo.URL)
if err != nil {
return PluginInfo{}, err
}
var pluginFoundWithIncompatibleBinary bool
for _, plugin := range pluginRepository.Plugins {
if plugin.Name == pluginName {
for _, pluginBinary := range plugin.Binaries {
if pluginBinary.Platform == platform {
return PluginInfo{Name: plugin.Name, Version: plugin.Version, URL: pluginBinary.URL, Checksum: pluginBinary.Checksum}, nil
}
}
pluginFoundWithIncompatibleBinary = true
}
}
if pluginFoundWithIncompatibleBinary {
return PluginInfo{}, NoCompatibleBinaryError{}
} else {
return PluginInfo{}, PluginNotFoundInRepositoryError{PluginName: pluginName, RepositoryName: pluginRepo.Name}
}
}