github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/kubeblocks/list_versions.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package kubeblocks 21 22 import ( 23 "fmt" 24 "sort" 25 26 "github.com/Masterminds/semver/v3" 27 "github.com/pkg/errors" 28 "github.com/spf13/cobra" 29 "k8s.io/cli-runtime/pkg/genericiooptions" 30 "k8s.io/kubectl/pkg/util/templates" 31 32 "github.com/1aal/kubeblocks/pkg/cli/printer" 33 "github.com/1aal/kubeblocks/pkg/cli/types" 34 "github.com/1aal/kubeblocks/pkg/cli/util" 35 ) 36 37 const ( 38 defaultLimit = 10 39 ) 40 41 var ( 42 listVersionsExample = templates.Examples(` 43 # list KubeBlocks release versions 44 kbcli kubeblocks list-versions 45 46 # list KubeBlocks versions including development versions, such as alpha, beta and release candidate 47 kbcli kubeblocks list-versions --devel`) 48 ) 49 50 type listVersionsOption struct { 51 genericiooptions.IOStreams 52 version string 53 devel bool 54 limit int 55 } 56 57 func newListVersionsCmd(streams genericiooptions.IOStreams) *cobra.Command { 58 o := listVersionsOption{IOStreams: streams} 59 cmd := &cobra.Command{ 60 Use: "list-versions", 61 Short: "List KubeBlocks versions.", 62 Aliases: []string{"ls-versions"}, 63 Args: cobra.NoArgs, 64 Example: listVersionsExample, 65 Run: func(cmd *cobra.Command, args []string) { 66 util.CheckErr(o.listVersions()) 67 }, 68 } 69 70 cmd.Flags().BoolVar(&o.devel, "devel", false, "Use development versions (alpha, beta, and release candidate releases), too. Equivalent to version '>0.0.0-0'.") 71 cmd.Flags().IntVar(&o.limit, "limit", defaultLimit, fmt.Sprintf("Maximum rows of versions to return, 0 means no limit (default %d)", defaultLimit)) 72 return cmd 73 } 74 75 func (o *listVersionsOption) listVersions() error { 76 if o.limit < 0 { 77 return fmt.Errorf("limit should be greater than or equal to 0") 78 } 79 80 // get chart versions 81 versions, err := getHelmChartVersions(types.KubeBlocksChartName) 82 if err != nil { 83 return err 84 } 85 86 // sort version descending and select the versions that meet the constraint 87 o.setupSearchedVersion() 88 sort.Sort(sort.Reverse(semver.Collection(versions))) 89 versions, err = o.applyConstraint(versions) 90 if err != nil { 91 return err 92 } 93 94 // print result 95 num := 0 96 tbl := printer.NewTablePrinter(o.Out) 97 tbl.SetHeader("VERSION", "RELEASE-NOTES") 98 for _, v := range versions { 99 tbl.AddRow(v.String(), fmt.Sprintf("https://github.com/1aal/kubeblocks/releases/tag/v%s", v)) 100 num += 1 101 if num == o.limit { 102 break 103 } 104 } 105 tbl.Print() 106 return nil 107 } 108 109 func (o *listVersionsOption) setupSearchedVersion() { 110 if o.devel { 111 o.version = ">0.0.0-0" 112 } else { 113 o.version = ">0.0.0" 114 } 115 } 116 117 func (o *listVersionsOption) applyConstraint(versions []*semver.Version) ([]*semver.Version, error) { 118 constraint, err := semver.NewConstraint(o.version) 119 if err != nil { 120 return nil, errors.Wrap(err, "an invalid version/constraint format") 121 } 122 123 var res []*semver.Version 124 found := map[string]bool{} 125 for _, version := range versions { 126 if found[version.String()] { 127 continue 128 } 129 if constraint.Check(version) { 130 res = append(res, version) 131 found[version.String()] = true 132 } 133 } 134 return res, nil 135 }