code.cloudfoundry.org/cli@v7.1.0+incompatible/actor/pluginaction/plugin_info.go (about)

     1  package pluginaction
     2  
     3  import (
     4  	"runtime"
     5  
     6  	"code.cloudfoundry.org/cli/actor/actionerror"
     7  	"code.cloudfoundry.org/cli/util/configv3"
     8  	"code.cloudfoundry.org/cli/util/generic"
     9  )
    10  
    11  type PluginInfo struct {
    12  	Name     string
    13  	Version  string
    14  	URL      string
    15  	Checksum string
    16  }
    17  
    18  // GetPluginInfoFromRepositoriesForPlatform returns the newest version of the specified plugin
    19  // and all the repositories that contain that version.
    20  func (actor Actor) GetPluginInfoFromRepositoriesForPlatform(pluginName string, pluginRepos []configv3.PluginRepository, platform string) (PluginInfo, []string, error) {
    21  	var reposWithPlugin []string
    22  	var newestPluginInfo PluginInfo
    23  	var pluginFoundWithIncompatibleBinary bool
    24  
    25  	for _, repo := range pluginRepos {
    26  		pluginInfo, err := actor.getPluginInfoFromRepositoryForPlatform(pluginName, repo, platform)
    27  		switch err.(type) {
    28  		case actionerror.PluginNotFoundInRepositoryError:
    29  			continue
    30  		case actionerror.NoCompatibleBinaryError:
    31  			pluginFoundWithIncompatibleBinary = true
    32  			continue
    33  		case nil:
    34  			if len(reposWithPlugin) == 0 || lessThan(newestPluginInfo.Version, pluginInfo.Version) {
    35  				newestPluginInfo = pluginInfo
    36  				reposWithPlugin = []string{repo.Name}
    37  			} else if pluginInfo.Version == newestPluginInfo.Version {
    38  				reposWithPlugin = append(reposWithPlugin, repo.Name)
    39  			}
    40  		default:
    41  			return PluginInfo{}, nil, actionerror.FetchingPluginInfoFromRepositoryError{
    42  				RepositoryName: repo.Name,
    43  				Err:            err,
    44  			}
    45  		}
    46  	}
    47  
    48  	if len(reposWithPlugin) == 0 {
    49  		if pluginFoundWithIncompatibleBinary {
    50  			return PluginInfo{}, nil, actionerror.NoCompatibleBinaryError{}
    51  		}
    52  		return PluginInfo{}, nil, actionerror.PluginNotFoundInAnyRepositoryError{PluginName: pluginName}
    53  	}
    54  	return newestPluginInfo, reposWithPlugin, nil
    55  }
    56  
    57  // GetPlatformString exists solely for the purposes of mocking it out for command-layers tests.
    58  func (actor Actor) GetPlatformString(runtimeGOOS string, runtimeGOARCH string) string {
    59  	return generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH)
    60  }
    61  
    62  // getPluginInfoFromRepositoryForPlatform returns the plugin info, if found, from
    63  // the specified repository for the specified platform.
    64  func (actor Actor) getPluginInfoFromRepositoryForPlatform(pluginName string, pluginRepo configv3.PluginRepository, platform string) (PluginInfo, error) {
    65  	pluginRepository, err := actor.client.GetPluginRepository(pluginRepo.URL)
    66  	if err != nil {
    67  		return PluginInfo{}, err
    68  	}
    69  
    70  	var pluginFoundWithIncompatibleBinary bool
    71  
    72  	for _, plugin := range pluginRepository.Plugins {
    73  		if plugin.Name == pluginName {
    74  			for _, pluginBinary := range plugin.Binaries {
    75  				if pluginBinary.Platform == platform {
    76  					return PluginInfo{
    77  						Name:     plugin.Name,
    78  						Version:  plugin.Version,
    79  						URL:      pluginBinary.URL,
    80  						Checksum: pluginBinary.Checksum,
    81  					}, nil
    82  				}
    83  			}
    84  			pluginFoundWithIncompatibleBinary = true
    85  		}
    86  	}
    87  
    88  	if pluginFoundWithIncompatibleBinary {
    89  		return PluginInfo{}, actionerror.NoCompatibleBinaryError{}
    90  	}
    91  
    92  	return PluginInfo{}, actionerror.PluginNotFoundInRepositoryError{
    93  		PluginName:     pluginName,
    94  		RepositoryName: pluginRepo.Name,
    95  	}
    96  }