github.com/getgauge/gauge@v1.6.9/plugin/pluginInfo/pluginInfo.go (about)

     1  /*----------------------------------------------------------------
     2   *  Copyright (c) ThoughtWorks, Inc.
     3   *  Licensed under the Apache License, Version 2.0
     4   *  See LICENSE in the project root for license information.
     5   *----------------------------------------------------------------*/
     6  
     7  package pluginInfo
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"path/filepath"
    13  	"sort"
    14  	"strings"
    15  
    16  	"github.com/getgauge/common"
    17  	"github.com/getgauge/gauge/version"
    18  )
    19  
    20  type PluginInfo struct {
    21  	Name    string
    22  	Version *version.Version
    23  	Path    string
    24  }
    25  
    26  type byPluginName []PluginInfo
    27  
    28  func (a byPluginName) Len() int      { return len(a) }
    29  func (a byPluginName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
    30  func (a byPluginName) Less(i, j int) bool {
    31  	return a[i].Name < a[j].Name
    32  }
    33  
    34  type byPath []PluginInfo
    35  
    36  func (a byPath) Len() int      { return len(a) }
    37  func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
    38  func (a byPath) Less(i, j int) bool {
    39  	return a[i].Path > a[j].Path
    40  }
    41  
    42  func GetPluginsInfo() ([]PluginInfo, error) {
    43  	allPluginsWithVersion, err := GetAllInstalledPluginsWithVersion()
    44  	if err != nil {
    45  		return nil, fmt.Errorf("No plugins found\nPlugins can be installed with `gauge install {plugin-name}`")
    46  	}
    47  	return allPluginsWithVersion, nil
    48  }
    49  
    50  // GetAllInstalledPluginsWithVersion Fetches Latest version of all installed plugins.
    51  var GetAllInstalledPluginsWithVersion = func() ([]PluginInfo, error) {
    52  	pluginInstallPrefixes, err := common.GetPluginInstallPrefixes()
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  	allPlugins := make(map[string]PluginInfo)
    57  	for _, prefix := range pluginInstallPrefixes {
    58  		files, err := os.ReadDir(prefix)
    59  		if err != nil {
    60  			return nil, err
    61  		}
    62  		for _, file := range files {
    63  			pluginDir, err := os.Stat(filepath.Join(prefix, file.Name()))
    64  			if err != nil {
    65  				continue
    66  			}
    67  
    68  			if !pluginDir.IsDir() {
    69  				continue
    70  			}
    71  			latestPlugin, err := GetLatestInstalledPlugin(filepath.Join(prefix, file.Name()))
    72  			if err != nil {
    73  				continue
    74  			}
    75  			allPlugins[file.Name()] = *latestPlugin
    76  		}
    77  	}
    78  	return sortPlugins(allPlugins), nil
    79  }
    80  
    81  func GetLatestInstalledPlugin(pluginDir string) (*PluginInfo, error) {
    82  	files, err := os.ReadDir(pluginDir)
    83  	if err != nil {
    84  		return nil, fmt.Errorf("Error listing files in plugin directory %s: %s", pluginDir, err.Error())
    85  	}
    86  	versionToPlugins := make(map[string][]PluginInfo)
    87  	pluginName := filepath.Base(pluginDir)
    88  
    89  	for _, file := range files {
    90  		if !file.IsDir() {
    91  			continue
    92  		}
    93  		v := file.Name()
    94  		if strings.Contains(file.Name(), "nightly") {
    95  			v = file.Name()[:strings.LastIndex(file.Name(), ".")]
    96  		}
    97  		vp, err := version.ParseVersion(v)
    98  		if err == nil {
    99  			versionToPlugins[v] = append(versionToPlugins[v], PluginInfo{pluginName, vp, filepath.Join(pluginDir, file.Name())})
   100  		}
   101  	}
   102  
   103  	if len(versionToPlugins) < 1 {
   104  		return nil, fmt.Errorf("No valid versions of plugin %s found in %s", pluginName, pluginDir)
   105  	}
   106  
   107  	var availableVersions []*version.Version
   108  	for k := range versionToPlugins {
   109  		vp, _ := version.ParseVersion(k)
   110  		availableVersions = append(availableVersions, vp)
   111  	}
   112  	latestVersion := version.GetLatestVersion(availableVersions)
   113  	latestBuild := getLatestOf(versionToPlugins[latestVersion.String()], latestVersion)
   114  	return &latestBuild, nil
   115  }
   116  
   117  func getLatestOf(plugins []PluginInfo, latestVersion *version.Version) PluginInfo {
   118  	for _, v := range plugins {
   119  		if v.Path == latestVersion.String() {
   120  			return v
   121  		}
   122  	}
   123  	sort.Sort(byPath(plugins))
   124  	return plugins[0]
   125  }
   126  
   127  func sortPlugins(allPlugins map[string]PluginInfo) []PluginInfo {
   128  	var installedPlugins []PluginInfo
   129  	for _, plugin := range allPlugins {
   130  		installedPlugins = append(installedPlugins, plugin)
   131  	}
   132  	sort.Sort(byPluginName(installedPlugins))
   133  	return installedPlugins
   134  }