mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 08:02:15 +03:00
880182c805
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7399 GitOrigin-RevId: 6e848f6eae2e5418c386f814623c122646db12c7
150 lines
4.1 KiB
Go
150 lines
4.1 KiB
Go
package commands
|
|
|
|
/*
|
|
some of the code here is borrowed from the krew codebse (kubernetes)
|
|
and the copyright belongs to the respective authors.
|
|
|
|
source: https://github.com/kubernetes-sigs/krew/blob/master/cmd/krew/cmd/list.go
|
|
*/
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"runtime"
|
|
"sort"
|
|
"strings"
|
|
"text/tabwriter"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/hasura/graphql-engine/cli/v2"
|
|
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
|
|
"github.com/hasura/graphql-engine/cli/v2/plugins"
|
|
)
|
|
|
|
func newPluginsListCmd(ec *cli.ExecutionContext) *cobra.Command {
|
|
opts := &pluginListOptions{
|
|
EC: ec,
|
|
}
|
|
pluginsListCmd := &cobra.Command{
|
|
Use: "list",
|
|
Aliases: []string{"ls"},
|
|
Short: "List all available plugins from index, versions and installation status",
|
|
Long: "To see a list of all the available plugins which extend the functionality of the CLI, their versions and installation status, run the list command.",
|
|
Example: ` # List all plugins
|
|
hasura plugins list
|
|
|
|
# The command also updates the plugin index that is cached locally
|
|
# To avoid updating the index, use the following flag:
|
|
hasura plugins list --dont-update-index`,
|
|
SilenceUsage: true,
|
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
|
op := genOpName(cmd, "PreRunE")
|
|
if err := ec.Prepare(); err != nil {
|
|
return errors.E(op, err)
|
|
}
|
|
return nil
|
|
},
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
op := genOpName(cmd, "RunE")
|
|
if err := opts.run(); err != nil {
|
|
return errors.E(op, err)
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
|
|
f := pluginsListCmd.Flags()
|
|
f.BoolVar(&opts.dontUpdateIndex, "dont-update-index", false, "don't update the plugin index local cache, only show the list")
|
|
|
|
return pluginsListCmd
|
|
}
|
|
|
|
type pluginListOptions struct {
|
|
EC *cli.ExecutionContext
|
|
|
|
dontUpdateIndex bool
|
|
}
|
|
|
|
func (p *pluginListOptions) run() error {
|
|
var op errors.Op = "commands.pluginListOptions.run"
|
|
if !p.dontUpdateIndex {
|
|
ec.Spin("Updating plugin index...")
|
|
err := p.EC.PluginsConfig.Repo.EnsureUpdated()
|
|
if err != nil {
|
|
p.EC.Logger.Warnf("unable to update plugin index %q", err)
|
|
}
|
|
}
|
|
ec.Spin("Fetching plugins list...")
|
|
defer ec.Spinner.Stop()
|
|
availablePlugins, err := ec.PluginsConfig.ListPlugins()
|
|
if err != nil {
|
|
return errors.E(op, fmt.Errorf("failed to load the list of plugins from the index: %w", err))
|
|
}
|
|
names := make([]string, 0, len(availablePlugins))
|
|
pluginMap := make(map[string]plugins.Plugin, len(availablePlugins))
|
|
for i, ap := range availablePlugins {
|
|
names = append(names, i)
|
|
latestVersion := ap.Index[len(ap.Index)-1]
|
|
pluginMap[i] = ap.Versions[latestVersion]
|
|
}
|
|
installed, err := ec.PluginsConfig.ListInstalledPlugins()
|
|
if err != nil {
|
|
return errors.E(op, fmt.Errorf("failed to load installed plugins: %w", err))
|
|
}
|
|
// No plugins found
|
|
if len(names) == 0 {
|
|
return nil
|
|
}
|
|
var rows [][]string
|
|
cols := []string{"NAME", "DESCRIPTION", "VERSION", "INSTALLED"}
|
|
for _, name := range names {
|
|
plugin := pluginMap[name]
|
|
var status string
|
|
var version string
|
|
if _, ok := installed[name]; ok {
|
|
status = "yes"
|
|
} else if _, ok, err := plugins.MatchPlatform(plugin.Platforms); err != nil {
|
|
return errors.E(op, fmt.Errorf("failed to get the matching platform for plugin %s: %w", name, err))
|
|
} else if ok {
|
|
status = "no"
|
|
} else {
|
|
status = "unavailable on " + runtime.GOOS
|
|
}
|
|
if status == "yes" {
|
|
version = installed[name]
|
|
} else {
|
|
version = plugin.Version
|
|
}
|
|
rows = append(rows, []string{name, limitString(plugin.ShortDescription, 50), version, status})
|
|
}
|
|
rows = sortByFirstColumn(rows)
|
|
ec.Spinner.Stop()
|
|
if err := printTable(p.EC.Stdout, cols, rows); err != nil {
|
|
return errors.E(op, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func printTable(out io.Writer, columns []string, rows [][]string) error {
|
|
var op errors.Op = "commands.printTable"
|
|
w := tabwriter.NewWriter(out, 0, 0, 2, ' ', 0)
|
|
fmt.Fprint(w, strings.Join(columns, "\t"))
|
|
fmt.Fprintln(w)
|
|
for _, values := range rows {
|
|
fmt.Fprint(w, strings.Join(values, "\t"))
|
|
fmt.Fprintln(w)
|
|
}
|
|
if err := w.Flush(); err != nil {
|
|
return errors.E(op, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func sortByFirstColumn(rows [][]string) [][]string {
|
|
sort.Slice(rows, func(a, b int) bool {
|
|
return rows[a][0] < rows[b][0]
|
|
})
|
|
return rows
|
|
}
|