-
Notifications
You must be signed in to change notification settings - Fork 0
/
listavailable.go
138 lines (114 loc) · 3.47 KB
/
listavailable.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
132
133
134
135
136
137
138
package registry
import (
"fmt"
"log"
"runtime"
"sort"
"strings"
"github.com/alecthomas/kong"
"github.com/blang/semver/v4"
"github.com/gideaworx/terraform-exporter-plugin-registry/registry"
"github.com/gideaworx/terraform-exporter/runner"
"github.com/olekukonko/tablewriter"
)
type ListAvailablePlugins struct {
Name string `short:"n" default:"default" help:"The registry to list available plugins from"`
ExcludeInstalled bool `short:"x" help:"If true, hide plugins that are already installed"`
ShowAllArchitectures bool `short:"a" help:"If true, show plugins available for any architecture, not just the local architecture"`
r *PluginRegistries
}
func (l *ListAvailablePlugins) BeforeApply() error {
var err error
l.r, err = LoadFromDisk()
return err
}
func (l *ListAvailablePlugins) Run(ctx *kong.Context) error {
registry := l.r.Get(l.Name)
if registry == nil {
return fmt.Errorf("plugin registry %q not found", l.Name)
}
if err := registry.LazyLoad(); err != nil {
return err
}
for i := range registry.Plugins {
sort.Slice(registry.Plugins[i].Versions, func(a, b int) bool {
sa, _ := semver.ParseTolerant(registry.Plugins[i].Versions[a].Version)
sb, _ := semver.ParseTolerant(registry.Plugins[i].Versions[b].Version)
return sa.GT(sb)
})
}
sort.Slice(registry.Plugins, func(i, j int) bool {
return registry.Plugins[i].Name < registry.Plugins[j].Name
})
headers := []string{"Name", "Description", "Latest Version"}
columnColors := []tablewriter.Colors{
{tablewriter.FgCyanColor},
{tablewriter.FgWhiteColor},
{tablewriter.FgGreenColor},
}
if !l.ExcludeInstalled {
headers = append(headers, "Installed")
columnColors = append(columnColors, tablewriter.Colors{tablewriter.FgWhiteColor})
}
headerColors := make([]tablewriter.Colors, len(headers))
for i := 0; i < len(headers); i++ {
headerColors[i] = tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiWhiteColor}
}
table := tablewriter.NewWriter(ctx.Stdout)
table.SetAutoWrapText(false)
table.SetHeader(headers)
table.SetHeaderAlignment(tablewriter.ALIGN_CENTER)
table.SetHeaderColor(headerColors...)
table.SetColumnColor(columnColors...)
for _, plugin := range registry.Plugins {
if !l.exclude(plugin) {
row := []string{plugin.Name, plugin.Description, plugin.Versions[0].Version}
if !l.ExcludeInstalled {
installed := ""
if l.isInstalled(plugin) {
installed = "✅"
}
row = append(row, installed)
}
table.Append(row)
}
}
table.Render()
return nil
}
func (l *ListAvailablePlugins) exclude(plugin registry.Plugin) bool {
if l.ShowAllArchitectures && !l.ExcludeInstalled {
return true
}
latestVersion := plugin.Versions[0]
if !l.ShowAllArchitectures {
foundArch := false
goos := runtime.GOOS
goarch := runtime.GOARCH
arch := registry.TargetArchitecture(fmt.Sprintf("%s/%s", strings.ToLower(goos), strings.ToLower(goarch)))
for availableArch := range latestVersion.DownloadInfo {
if arch == availableArch || availableArch == registry.MultiArch {
foundArch = true
break
}
}
if !foundArch {
return false
}
}
return l.ExcludeInstalled && l.isInstalled(plugin)
}
func (l *ListAvailablePlugins) isInstalled(plugin registry.Plugin) bool {
boms, err := runner.LoadInstalledBOMs()
if err != nil {
log.Println(err)
return false
}
for _, bom := range boms {
if bom.Name == plugin.Name &&
bom.Version.String() == plugin.Versions[0].Version {
return true
}
}
return false
}