From 772ea69fa26ac59ec066cf9a97d9718b7cf6c281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E5=85=83?= Date: Fri, 7 Aug 2020 15:08:35 +0800 Subject: [PATCH 1/2] remove kube flags --- cmd/vela/main.go | 19 ++++++++----------- pkg/cmd/delete.go | 6 +++--- pkg/cmd/init.go | 2 +- pkg/cmd/ls.go | 2 +- pkg/cmd/traits.go | 2 +- pkg/cmd/workloads.go | 2 +- pkg/test/cli.go | 8 +++----- 7 files changed, 18 insertions(+), 23 deletions(-) diff --git a/cmd/vela/main.go b/cmd/vela/main.go index 28af5e35c..3e770f14c 100644 --- a/cmd/vela/main.go +++ b/cmd/vela/main.go @@ -7,12 +7,13 @@ import ( "runtime" "time" + "sigs.k8s.io/controller-runtime/pkg/client/config" + "github.com/cloud-native-application/rudrx/pkg/utils/system" "github.com/crossplane/oam-kubernetes-runtime/apis/core" "github.com/spf13/cobra" k8sruntime "k8s.io/apimachinery/pkg/runtime" - "k8s.io/cli-runtime/pkg/genericclioptions" clientgoscheme "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" @@ -65,11 +66,7 @@ func newCommand() *cobra.Command { SilenceUsage: true, } - flags := cmds.PersistentFlags() - kubeConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag() - kubeConfigFlags.AddFlags(flags) - f := cmdutil.NewFactory(kubeConfigFlags) - restConf, err := f.ToRESTConfig() + restConf, err := config.GetConfig() if err != nil { fmt.Println("get kubeconfig err", err) os.Exit(1) @@ -89,12 +86,12 @@ func newCommand() *cobra.Command { } cmds.AddCommand( - cmd.NewTraitsCommand(f, client, ioStream, []string{}), - cmd.NewWorkloadsCommand(f, client, ioStream, os.Args[1:]), - cmd.NewAdminInitCommand(f, client, ioStream), + cmd.NewTraitsCommand(client, ioStream, []string{}), + cmd.NewWorkloadsCommand(client, ioStream, os.Args[1:]), + cmd.NewAdminInitCommand(client, ioStream), cmd.NewAdminInfoCommand(VelaVersion, ioStream), - cmd.NewDeleteCommand(f, client, ioStream, os.Args[1:]), - cmd.NewAppsCommand(f, client, ioStream), + cmd.NewDeleteCommand(client, ioStream, os.Args[1:]), + cmd.NewAppsCommand(client, ioStream), cmd.NewEnvInitCommand(client, ioStream), cmd.NewEnvSwitchCommand(ioStream), cmd.NewEnvDeleteCommand(ioStream), diff --git a/pkg/cmd/delete.go b/pkg/cmd/delete.go index f5e60f35b..c853eace3 100644 --- a/pkg/cmd/delete.go +++ b/pkg/cmd/delete.go @@ -37,7 +37,7 @@ func newDeleteCommand() *cobra.Command { } // NewDeleteCommand init new command -func NewDeleteCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command { +func NewDeleteCommand(c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command { cmd := newDeleteCommand() cmd.SetArgs(args) cmd.SetOut(ioStreams.Out) @@ -45,7 +45,7 @@ func NewDeleteCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOSt o.client = c o.Env, _ = GetEnv() cmd.RunE = func(cmd *cobra.Command, args []string) error { - if err := o.Complete(f, cmd, args); err != nil { + if err := o.Complete(cmd, args); err != nil { return err } return o.Delete() @@ -53,7 +53,7 @@ func NewDeleteCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOSt return cmd } -func (o *deleteOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { +func (o *deleteOptions) Complete(cmd *cobra.Command, args []string) error { if len(args) < 1 { return errors.New("must specify name for workload") diff --git a/pkg/cmd/init.go b/pkg/cmd/init.go index fd7af0709..713cc7837 100644 --- a/pkg/cmd/init.go +++ b/pkg/cmd/init.go @@ -109,7 +109,7 @@ func (i *infoCmd) run(version string, ioStreams cmdutil.IOStreams) error { return nil } -func NewAdminInitCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams) *cobra.Command { +func NewAdminInitCommand(c client.Client, ioStreams cmdutil.IOStreams) *cobra.Command { i := &initCmd{out: ioStreams.Out} diff --git a/pkg/cmd/ls.go b/pkg/cmd/ls.go index 6707fb593..318c6ed60 100644 --- a/pkg/cmd/ls.go +++ b/pkg/cmd/ls.go @@ -12,7 +12,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -func NewAppsCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams) *cobra.Command { +func NewAppsCommand(c client.Client, ioStreams cmdutil.IOStreams) *cobra.Command { ctx := context.Background() cmd := &cobra.Command{ Use: "app:ls", diff --git a/pkg/cmd/traits.go b/pkg/cmd/traits.go index 8013e5f3e..dcf987596 100644 --- a/pkg/cmd/traits.go +++ b/pkg/cmd/traits.go @@ -12,7 +12,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -func NewTraitsCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command { +func NewTraitsCommand(c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command { ctx := context.Background() var workloadName string cmd := &cobra.Command{ diff --git a/pkg/cmd/workloads.go b/pkg/cmd/workloads.go index 76c7fe8a5..81c8d0ca7 100644 --- a/pkg/cmd/workloads.go +++ b/pkg/cmd/workloads.go @@ -11,7 +11,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -func NewWorkloadsCommand(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command { +func NewWorkloadsCommand(c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command { ctx := context.Background() cmd := &cobra.Command{ Use: "workloads", diff --git a/pkg/test/cli.go b/pkg/test/cli.go index 0d497ddb3..7203a6e73 100644 --- a/pkg/test/cli.go +++ b/pkg/test/cli.go @@ -8,7 +8,6 @@ import ( "gotest.tools/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - cmdtesting "k8s.io/kubectl/pkg/cmd/testing" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" @@ -50,12 +49,12 @@ type clitestImpl struct { cases map[string]*CliTestCase t *testing.T scheme *runtime.Scheme - command func(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command + command func(c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command } // NewCliTest return cli testimpl func NewCliTest(t *testing.T, scheme *runtime.Scheme, - command func(f cmdutil.Factory, c client.Client, ioStreams cmdutil.IOStreams, + command func(c client.Client, ioStreams cmdutil.IOStreams, args []string) *cobra.Command, cases map[string]*CliTestCase) CliTest { return &clitestImpl{ cases: cases, @@ -69,7 +68,6 @@ func NewCliTest(t *testing.T, scheme *runtime.Scheme, func (c *clitestImpl) Run() { for name, tc := range c.cases { c.t.Run(name, func(t *testing.T) { - factory := cmdtesting.NewTestFactory().WithNamespace("default") fakeClient := fake.NewFakeClientWithScheme(c.scheme) iostream, _, outPut, _ := cmdutil.NewTestIOStreams() @@ -88,7 +86,7 @@ func (c *clitestImpl) Run() { } // init command - runCmd := c.command(factory, fakeClient, iostream, tc.Args) + runCmd := c.command(fakeClient, iostream, tc.Args) runCmd.SetOutput(outPut) err := runCmd.Execute() From 93240b4ae655a448bf5a733f74e62ff59eec4120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A9=E5=85=83?= Date: Fri, 7 Aug 2020 16:38:23 +0800 Subject: [PATCH 2/2] make env help pretty --- pkg/cmd/env.go | 61 +++++++++++++++++++++++++------------- pkg/cmd/env_test.go | 15 ++++++---- pkg/cmd/util/helpers.go | 42 ++++++++++++++++++++++++++ pkg/utils/system/system.go | 16 ++++++---- 4 files changed, 101 insertions(+), 33 deletions(-) diff --git a/pkg/cmd/env.go b/pkg/cmd/env.go index c985bbb2d..e0cea1b40 100644 --- a/pkg/cmd/env.go +++ b/pkg/cmd/env.go @@ -21,6 +21,29 @@ import ( "github.com/spf13/cobra" ) +func NewEnvCommand(ioStreams cmdutil.IOStreams) *cobra.Command { + ctx := context.Background() + cmd := &cobra.Command{ + Use: "env", + DisableFlagsInUseLine: true, + Short: "List environments", + Long: "List all environments", + Example: `vela env [env-name]`, + RunE: func(cmd *cobra.Command, args []string) error { + return ListEnvs(ctx, args, ioStreams) + }, + } + cmd.SetOut(ioStreams.Out) + cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) { + cmdutil.PrintUsageIntroduce(cmd, "Prepare environments for applications") + subcmds := []*cobra.Command{cmd, NewEnvInitCommand(nil, ioStreams), NewEnvSwitchCommand(ioStreams), NewEnvDeleteCommand(ioStreams)} + cmdutil.PrintUsage(cmd, subcmds) + cmdutil.PrintExample(cmd, subcmds) + cmdutil.PrintFlags(cmd, subcmds) + }) + return cmd +} + func NewEnvInitCommand(c client.Client, ioStreams cmdutil.IOStreams) *cobra.Command { var envArgs types.EnvMeta ctx := context.Background() @@ -55,22 +78,6 @@ func NewEnvDeleteCommand(ioStreams cmdutil.IOStreams) *cobra.Command { return cmd } -func NewEnvCommand(ioStreams cmdutil.IOStreams) *cobra.Command { - ctx := context.Background() - cmd := &cobra.Command{ - Use: "env", - DisableFlagsInUseLine: true, - Short: "List environments", - Long: "List all environments", - Example: `vela env [env-name]`, - RunE: func(cmd *cobra.Command, args []string) error { - return ListEnvs(ctx, args, ioStreams) - }, - } - cmd.SetOut(ioStreams.Out) - return cmd -} - func NewEnvSwitchCommand(ioStreams cmdutil.IOStreams) *cobra.Command { ctx := context.Background() cmd := &cobra.Command{ @@ -78,7 +85,7 @@ func NewEnvSwitchCommand(ioStreams cmdutil.IOStreams) *cobra.Command { DisableFlagsInUseLine: true, Short: "Switch environments", Long: "switch to another environment", - Example: `vela env test`, + Example: `vela env:sw test`, RunE: func(cmd *cobra.Command, args []string) error { return SwitchEnv(ctx, args, ioStreams) }, @@ -90,15 +97,19 @@ func NewEnvSwitchCommand(ioStreams cmdutil.IOStreams) *cobra.Command { func ListEnvs(ctx context.Context, args []string, ioStreams cmdutil.IOStreams) error { table := uitable.New() table.MaxColWidth = 60 - table.AddRow("NAME", "NAMESPACE") + table.AddRow("NAME", "CURRENT", "NAMESPACE") if len(args) > 0 { envName := args[0] env, err := getEnvByName(envName) if err != nil { + if os.IsNotExist(err) { + ioStreams.Info(fmt.Sprintf("env %s not exist", envName)) + return nil + } return err } table.AddRow(envName, env.Namespace) - ioStreams.Infof(table.String()) + ioStreams.Info(table.String()) return nil } envDir, err := system.GetEnvDir() @@ -109,6 +120,10 @@ func ListEnvs(ctx context.Context, args []string, ioStreams cmdutil.IOStreams) e if err != nil { return err } + curEnv, err := GetCurrentEnvName() + if err != nil { + curEnv = types.DefaultEnvName + } for _, f := range files { if f.IsDir() { continue @@ -121,9 +136,13 @@ func ListEnvs(ctx context.Context, args []string, ioStreams cmdutil.IOStreams) e if err = json.Unmarshal(data, &envMeta); err != nil { continue } - table.AddRow(f.Name(), envMeta.Namespace) + if curEnv == f.Name() { + table.AddRow(f.Name(), "*", envMeta.Namespace) + } else { + table.AddRow(f.Name(), "", envMeta.Namespace) + } } - ioStreams.Infof(table.String()) + ioStreams.Info(table.String()) return nil } diff --git a/pkg/cmd/env_test.go b/pkg/cmd/env_test.go index 1d27e211b..045d8f843 100644 --- a/pkg/cmd/env_test.go +++ b/pkg/cmd/env_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "os" + "strings" "testing" "github.com/crossplane/crossplane-runtime/pkg/test" @@ -19,8 +20,13 @@ import ( func TestENV(t *testing.T) { ctx := context.Background() + assert.NoError(t, os.Setenv(system.VelaHomeEnv, ".test_vela")) + home, err := system.GetVelaHomeDir() + assert.NoError(t, err) + assert.Equal(t, true, strings.HasSuffix(home, ".test_vela")) + defer os.RemoveAll(home) // Create Default Env - err := system.InitDefaultEnv() + err = system.InitDefaultEnv() assert.NoError(t, err) // check and compare create default env success @@ -55,14 +61,11 @@ func TestENV(t *testing.T) { ioStream.Out = &b err = ListEnvs(ctx, []string{}, ioStream) assert.NoError(t, err) - assert.Equal(t, `NAME NAMESPACE -default default -env1 test1 `, b.String()) + assert.Equal(t, "NAME \tCURRENT\tNAMESPACE\ndefault\t \tdefault \nenv1 \t* \ttest1 \n", b.String()) b.Reset() err = ListEnvs(ctx, []string{"env1"}, ioStream) assert.NoError(t, err) - assert.Equal(t, `NAME NAMESPACE -env1 test1 `, b.String()) + assert.Equal(t, "NAME\tCURRENT\tNAMESPACE\nenv1\ttest1 \n", b.String()) ioStream.Out = os.Stdout // can not delete current env diff --git a/pkg/cmd/util/helpers.go b/pkg/cmd/util/helpers.go index 344b3ffa8..7606b80d4 100644 --- a/pkg/cmd/util/helpers.go +++ b/pkg/cmd/util/helpers.go @@ -5,6 +5,8 @@ import ( "os" "strings" + "github.com/spf13/cobra" + "github.com/cloud-native-application/rudrx/api/types" corev1alpha2 "github.com/crossplane/oam-kubernetes-runtime/apis/core/v1alpha2" @@ -270,3 +272,43 @@ func GetWorkloadDefinitionByAlias(ctx context.Context, c client.Client, traitAli return workloadDefinition, nil } + +func PrintUsageIntroduce(cmd *cobra.Command, introduce string) { + cmd.Println(introduce) + cmd.Println() +} + +func PrintUsage(cmd *cobra.Command, subcmds []*cobra.Command) { + printUsage := func(cmd *cobra.Command) { + useline := cmd.UseLine() + if !strings.HasPrefix(useline, "vela ") { + useline = "vela " + useline + } + cmd.Printf(" %s\t\t%s\n", useline, cmd.Long) + } + cmd.Println("Usage:") + for _, sub := range subcmds { + printUsage(sub) + } + cmd.Println() +} +func PrintExample(cmd *cobra.Command, subcmds []*cobra.Command) { + printExample := func(cmd *cobra.Command) { + cmd.Printf(" %s\n", cmd.Example) + } + cmd.Println("Examples:") + for _, sub := range subcmds { + printExample(sub) + } + cmd.Println() +} + +func PrintFlags(cmd *cobra.Command, subcmds []*cobra.Command) { + cmd.Println("Flags:") + for _, sub := range subcmds { + if sub.HasLocalFlags() { + fmt.Printf(sub.LocalFlags().FlagUsages()) + } + } + cmd.Println() +} diff --git a/pkg/utils/system/system.go b/pkg/utils/system/system.go index d94d6107b..ca34f63ec 100644 --- a/pkg/utils/system/system.go +++ b/pkg/utils/system/system.go @@ -9,14 +9,18 @@ import ( "github.com/cloud-native-application/rudrx/api/types" ) -const velaHome = ".vela" +const defaultVelaHome = ".vela" +const VelaHomeEnv = "VELA_HOME" func GetVelaHomeDir() (string, error) { + if custom := os.Getenv(VelaHomeEnv); custom != "" { + return custom, nil + } home, err := os.UserHomeDir() if err != nil { return "", err } - return filepath.Join(home, velaHome), nil + return filepath.Join(home, defaultVelaHome), nil } func GetApplicationDir() (string, error) { @@ -36,19 +40,19 @@ func GetDefinitionDir() (string, error) { } func GetEnvDir() (string, error) { - home, err := os.UserHomeDir() + homedir, err := GetVelaHomeDir() if err != nil { return "", err } - return filepath.Join(home, velaHome, "envs"), nil + return filepath.Join(homedir, "envs"), nil } func GetCurrentEnvPath() (string, error) { - home, err := os.UserHomeDir() + homedir, err := GetVelaHomeDir() if err != nil { return "", err } - return filepath.Join(home, velaHome, "curenv"), nil + return filepath.Join(homedir, "curenv"), nil } func InitDefinitionDir() error {