github.com/wanddynosios/cli/v8@v8.7.9-0.20240221182337-1a92e3a7017f/cf/actors/pluginrepo/plugin_repo.go (about)

     1  package pluginrepo
     2  
     3  import (
     4  	"code.cloudfoundry.org/cli/version"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"net/http"
     9  	"os"
    10  	"path/filepath"
    11  	"runtime"
    12  	"strings"
    13  
    14  	clipr "code.cloudfoundry.org/cli-plugin-repo/web"
    15  	"code.cloudfoundry.org/cli/cf/models"
    16  
    17  	. "code.cloudfoundry.org/cli/cf/i18n"
    18  )
    19  
    20  //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . PluginRepo
    21  
    22  type PluginRepo interface {
    23  	GetPlugins([]models.PluginRepo) (map[string][]clipr.Plugin, []string)
    24  }
    25  
    26  type pluginRepo struct{}
    27  
    28  func NewPluginRepo() PluginRepo {
    29  	return pluginRepo{}
    30  }
    31  
    32  func (r pluginRepo) GetPlugins(repos []models.PluginRepo) (map[string][]clipr.Plugin, []string) {
    33  	var pluginList clipr.PluginsJson
    34  	var repoError []string
    35  	repoPlugins := make(map[string][]clipr.Plugin)
    36  
    37  	for _, repo := range repos {
    38  		client := &http.Client{}
    39  		req, err := http.NewRequest("GET", getListEndpoint(repo.URL), nil)
    40  		if err != nil {
    41  			repoError = append(repoError, fmt.Sprintf(T("Error creating a request")+" '%s' - %s", repo.Name, err.Error()))
    42  			continue
    43  		}
    44  		userAgent := fmt.Sprintf("%s/%s (%s; %s %s)",
    45  			filepath.Base(os.Args[0]),
    46  			version.VersionString(),
    47  			runtime.Version(),
    48  			runtime.GOARCH,
    49  			runtime.GOOS,
    50  		)
    51  		req.Header.Set("User-Agent", userAgent)
    52  		resp, err := client.Do(req)
    53  		if err != nil {
    54  			repoError = append(repoError, fmt.Sprintf(T("Error requesting from")+" '%s' - %s", repo.Name, err.Error()))
    55  			continue
    56  		} else {
    57  			defer func(Body io.ReadCloser) {
    58  				err := Body.Close()
    59  				if err != nil {
    60  					repoError = append(repoError, fmt.Sprintf(T("Error closing body")+" '%s' - %s", repo.Name, err.Error()))
    61  				}
    62  			}(resp.Body)
    63  
    64  			body, err := io.ReadAll(resp.Body)
    65  			if err != nil {
    66  				repoError = append(repoError, fmt.Sprintf(T("Error reading response from")+" '%s' - %s ", repo.Name, err.Error()))
    67  				continue
    68  			}
    69  
    70  			pluginList = clipr.PluginsJson{Plugins: nil}
    71  			err = json.Unmarshal(body, &pluginList)
    72  			if err != nil {
    73  				repoError = append(repoError, fmt.Sprintf(T("Invalid json data from")+" '%s' - %s", repo.Name, err.Error()))
    74  				continue
    75  			} else if pluginList.Plugins == nil {
    76  				repoError = append(repoError, T("Invalid data from '{{.repoName}}' - plugin data does not exist", map[string]interface{}{"repoName": repo.Name}))
    77  				continue
    78  			}
    79  
    80  		}
    81  
    82  		repoPlugins[repo.Name] = pluginList.Plugins
    83  	}
    84  
    85  	return repoPlugins, repoError
    86  }
    87  
    88  func getListEndpoint(url string) string {
    89  	if strings.HasSuffix(url, "/") {
    90  		return url + "list"
    91  	}
    92  	return url + "/list"
    93  }