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