feat: add latest version and outdated flag to plugin list command

Signed-off-by: Suleiman Dibirov <idsulik@gmail.com>
pull/31403/head
Suleiman Dibirov 9 months ago
parent 490dffeb34
commit 5449005f59

@ -146,6 +146,11 @@ func (i *HTTPInstaller) Update() error {
return fmt.Errorf("method Update() not implemented for HttpInstaller")
}
// GetLatestVersion fetches the latest version of the plugin.Add a comment on lines R158 to R160Add diff commentMarkdown input: edit mode selected.WritePreviewAdd a suggestionHeadingBoldItalicQuoteCodeLinkUnordered listNumbered listTask listMentionReferenceSaved repliesAdd FilesPaste, drop, or click to add filesCancelCommentStart a reviewReturn to code
func (i *HTTPInstaller) GetLatestVersion() (string, error) {
return "", fmt.Errorf("not supported")
}
// Path is overridden because we want to join on the plugin name not the file name
func (i HTTPInstaller) Path() string {
if i.Source == "" {

@ -50,6 +50,8 @@ type Installer interface {
Path() string
// Update updates a plugin.
Update() error
// GetLatestVersion fetches the latest version of the plugin.
GetLatestVersion() (string, error)
}
// Verifier provides an interface for installers that support verification.

@ -164,6 +164,10 @@ func (i *LocalInstaller) Update() error {
return nil
}
func (i *LocalInstaller) GetLatestVersion() (string, error) {
return "", fmt.Errorf("not supported")
}
// Path is overridden to handle archive plugin names properly
func (i *LocalInstaller) Path() string {
if i.Source == "" {

@ -197,6 +197,10 @@ func (i OCIInstaller) Path() string {
return filepath.Join(i.settings.PluginsDirectory, i.PluginName)
}
func (i *OCIInstaller) GetLatestVersion() (string, error) {
return "", fmt.Errorf("not supported")
}
// extractTarGz extracts a gzipped tar archive to a directory
func extractTarGz(r io.Reader, targetDir string) error {
gzr, err := gzip.NewReader(r)

@ -110,6 +110,26 @@ func (i *VCSInstaller) Update() error {
return nil
}
func (i *VCSInstaller) GetLatestVersion() (string, error) {
_, err := i.Repo.RunFromDir("git", "fetch", "-q", "--tags")
if err != nil {
return "", fmt.Errorf("failed to fetch tags: %w", err)
}
refs, err := i.Repo.Tags()
if err != nil {
return "", fmt.Errorf("failed to get tags: %w", err)
}
semvers := getSemVers(refs)
if len(semvers) == 0 {
return "", fmt.Errorf("no valid semver tags found in repository")
}
sort.Sort(sort.Reverse(semver.Collection(semvers)))
return semvers[0].Original(), nil
}
func (i *VCSInstaller) solveVersion(repo vcs.Repo) (string, error) {
if i.Version == "" {
return "", nil

@ -24,12 +24,19 @@ import (
"github.com/gosuri/uitable"
"github.com/spf13/cobra"
"helm.sh/helm/v4/internal/plugin/installer"
"helm.sh/helm/v4/internal/plugin"
"helm.sh/helm/v4/internal/plugin/schema"
)
type pluginListOptions struct {
showOutdated bool
}
func newPluginListCmd(out io.Writer) *cobra.Command {
o := &pluginListOptions{}
var pluginType string
cmd := &cobra.Command{
Use: "list",
@ -51,7 +58,7 @@ func newPluginListCmd(out io.Writer) *cobra.Command {
signingInfo := plugin.GetSigningInfoForPlugins(plugins)
table := uitable.New()
table.AddRow("NAME", "VERSION", "TYPE", "APIVERSION", "PROVENANCE", "SOURCE")
table.AddRow("NAME", "VERSION", "LATEST", "TYPE", "APIVERSION", "PROVENANCE", "SOURCE")
for _, p := range plugins {
m := p.Metadata()
sourceURL := m.SourceURL
@ -63,7 +70,15 @@ func newPluginListCmd(out io.Writer) *cobra.Command {
if info, ok := signingInfo[m.Name]; ok {
signedStatus = info.Status
}
table.AddRow(m.Name, m.Version, m.Type, m.APIVersion, signedStatus, sourceURL)
latest, err := getLatestVersion(p)
if err != nil {
latest = "unknown"
}
if !o.showOutdated || (latest != "unknown" && latest != m.Version) {
table.AddRow(m.Name, m.Version, latest, m.Type, m.APIVersion, signedStatus, sourceURL)
}
}
fmt.Fprintln(out, table)
return nil
@ -72,6 +87,7 @@ func newPluginListCmd(out io.Writer) *cobra.Command {
f := cmd.Flags()
f.StringVar(&pluginType, "type", "", "Plugin type")
f.BoolVar(&o.showOutdated, "outdated", false, "show only outdated plugins")
return cmd
}
@ -115,3 +131,22 @@ func compListPlugins(_ string, ignoredPluginNames []string) []string {
}
return pNames
}
// getLatestVersion returns the latest version of a plugin
func getLatestVersion(p plugin.Plugin) (string, error) {
exactLocation, err := filepath.EvalSymlinks(p.Dir())
if err != nil {
return "", err
}
absExactLocation, err := filepath.Abs(exactLocation)
if err != nil {
return "", err
}
i, err := installer.FindSource(absExactLocation)
if err != nil {
return "", err
}
return i.GetLatestVersion()
}

Loading…
Cancel
Save