diff --git a/app/cmd/common.go b/app/cmd/common.go index 28691ece922bc4377319c21839c8695b60ce7562..0652457531fe733d9e3fa25bda32c421f3149268 100644 --- a/app/cmd/common.go +++ b/app/cmd/common.go @@ -3,6 +3,7 @@ package cmd import ( "encoding/json" "fmt" + "go.uber.org/zap" "gopkg.in/yaml.v2" "io" "net/http" @@ -36,9 +37,13 @@ type OutputOption struct { WithoutHeaders bool Filter []string - Writer io.Writer + Writer io.Writer + CellRenderMap map[string]RenderCell } +// RenderCell render a specific cell in a table +type RenderCell = func(string) string + // FormatOutput is the interface of format output type FormatOutput interface { Output(obj interface{}, format string) (data []byte, err error) @@ -78,6 +83,7 @@ func (o *OutputOption) OutputV2(obj interface{}) (err error) { return } + logger.Debug("start to output", zap.Any("filter", o.Filter)) obj = o.ListFilter(obj) var data []byte @@ -150,17 +156,38 @@ func (o *OutputOption) Match(item reflect.Value) bool { func (o *OutputOption) GetLine(obj reflect.Value) []string { columns := strings.Split(o.Columns, ",") values := make([]string, 0) + + if o.CellRenderMap == nil { + o.CellRenderMap = make(map[string]RenderCell, 0) + } + for _, col := range columns { - values = append(values, util.ReflectFieldValueAsString(obj, col)) + cell := util.ReflectFieldValueAsString(obj, col) + if renderCell, ok := o.CellRenderMap[col]; ok && renderCell != nil { + cell = renderCell(cell) + } + + values = append(values, cell) } return values } // SetFlag set flag of output format +// Deprecated, see also SetFlagWithHeaders func (o *OutputOption) SetFlag(cmd *cobra.Command) { - cmd.Flags().StringVarP(&o.Format, "output", "o", TableOutputFormat, "Format the output, supported formats: table, json, yaml") + cmd.Flags().StringVarP(&o.Format, "output", "o", TableOutputFormat, + i18n.T("Format the output, supported formats: table, json, yaml")) cmd.Flags().BoolVarP(&o.WithoutHeaders, "no-headers", "", false, - `When using the default output format, don't print headers (default print headers)`) + i18n.T(`When using the default output format, don't print headers (default print headers)`)) + cmd.Flags().StringArrayVarP(&o.Filter, "filter", "", []string{}, + i18n.T("Filter for the list by fields")) +} + +// SetFlagWithHeaders set the flags of output +func (o *OutputOption) SetFlagWithHeaders(cmd *cobra.Command, headers string) { + o.SetFlag(cmd) + cmd.Flags().StringVarP(&o.Columns, "columns", "", headers, + i18n.T("The columns of table")) } // BatchOption represent the options for a batch operation diff --git a/app/cmd/computer_list.go b/app/cmd/computer_list.go index dc9bf2bcb2af2fbe3542e17a6b853b6ab98d8231..7318c209d28f7309b1fa929af224f631b98ab245 100644 --- a/app/cmd/computer_list.go +++ b/app/cmd/computer_list.go @@ -1,8 +1,6 @@ package cmd import ( - "bytes" - "fmt" "net/http" "github.com/jenkins-zh/jenkins-cli/client" @@ -24,7 +22,7 @@ var computerListOption ComputerListOption func init() { computerCmd.AddCommand(computerListCmd) - computerListOption.SetFlag(computerListCmd) + computerListOption.SetFlagWithHeaders(computerListCmd, "DisplayName,NumExecutors,Description,Offline") } var computerListCmd = &cobra.Command{ @@ -41,39 +39,18 @@ var computerListCmd = &cobra.Command{ var computers client.ComputerList if computers, err = jClient.List(); err == nil { - var data []byte - data, err = computerListOption.Output(computers.Computer) - if err == nil && len(data) > 0 { - cmd.Print(string(data)) + computerListOption.Writer = cmd.OutOrStdout() + computerListOption.CellRenderMap = map[string]RenderCell{ + "Offline": func(offline string) string { + switch offline { + case "true": + return util.ColorWarning("yes") + } + return "no" + }, } + err = computerListOption.OutputV2(computers.Computer) } return }, } - -// Output render data into byte array as a table format -func (o *ComputerListOption) Output(obj interface{}) (data []byte, err error) { - if data, err = o.OutputOption.Output(obj); err != nil && o.Format == TableOutputFormat { - computers := obj.([]client.Computer) - - buf := new(bytes.Buffer) - table := util.CreateTableWithHeader(buf, o.WithoutHeaders) - table.AddHeader("number", "name", "executors", "description", "offline") - for i, computer := range computers { - table.AddRow(fmt.Sprintf("%d", i), computer.DisplayName, - fmt.Sprintf("%d", computer.NumExecutors), computer.Description, - colorOffline(computer.Offline)) - } - table.Render() - err = nil - data = buf.Bytes() - } - return -} - -func colorOffline(offline bool) string { - if offline { - return util.ColorWarning("yes") - } - return "no" -} diff --git a/app/cmd/config_list.go b/app/cmd/config_list.go index 9a65dd448d539f42f26424553894b2460676fa45..8ec197cc8cf8e448953f4d6ac0f53087359b3a36 100644 --- a/app/cmd/config_list.go +++ b/app/cmd/config_list.go @@ -1,62 +1,53 @@ package cmd import ( - "bytes" "fmt" - - "github.com/jenkins-zh/jenkins-cli/app/helper" "github.com/jenkins-zh/jenkins-cli/app/i18n" - "github.com/jenkins-zh/jenkins-cli/util" "github.com/spf13/cobra" ) // ConfigListOption option for config list command type ConfigListOption struct { OutputOption + + Config string } var configListOption ConfigListOption func init() { configCmd.AddCommand(configListCmd) - configListOption.SetFlag(configListCmd) + configListCmd.Flags().StringVarP(&configListOption.Config, "config", "", "JenkinsServers", + i18n.T("The type of config items, contains PreHooks, PostHooks, Mirrors, PluginSuites")) + configListOption.SetFlagWithHeaders(configListCmd, "Name,URL,Description") } var configListCmd = &cobra.Command{ Use: "list", Short: i18n.T("List all Jenkins config items"), Long: i18n.T("List all Jenkins config items"), - Run: func(cmd *cobra.Command, _ []string) { - current := getCurrentJenkins() - - data, err := configListOption.Output(current) - cmd.Print(string(data)) - helper.CheckErr(cmd, err) - }, -} - -// Output render data into byte array as a table format -func (o *ConfigListOption) Output(obj interface{}) (data []byte, err error) { - if data, err = o.OutputOption.Output(obj); err != nil && o.Format == TableOutputFormat { - current := obj.(*JenkinsServer) - - buf := new(bytes.Buffer) - table := util.CreateTableWithHeader(buf, o.WithoutHeaders) - table.AddHeader("number", "name", "url", "description") - for i, jenkins := range getConfig().JenkinsServers { - name := jenkins.Name - if name == current.Name { - name = fmt.Sprintf("*%s", name) - } - if len(jenkins.Description) > 15 { - jenkins.Description = jenkins.Description[0:15] - } - table.AddRow(fmt.Sprintf("%d", i), name, jenkins.URL, jenkins.Description) + RunE: func(cmd *cobra.Command, _ []string) (err error) { + configListOption.Writer = cmd.OutOrStdout() + + switch configListOption.Config { + case "JenkinsServers": + err = configListOption.OutputV2(getConfig().JenkinsServers) + case "PreHooks": + configListOption.Columns = "Path,Command" + err = configListOption.OutputV2(getConfig().PreHooks) + case "PostHooks": + configListOption.Columns = "Path,Command" + err = configListOption.OutputV2(getConfig().PostHooks) + case "Mirrors": + configListOption.Columns = "Name,URL" + err = configListOption.OutputV2(getConfig().Mirrors) + case "PluginSuites": + configListOption.Columns = "Name,Description" + err = configListOption.OutputV2(getConfig().PluginSuites) + default: + err = fmt.Errorf("unknow config %s", configListOption.Config) } - table.Render() - err = nil - data = buf.Bytes() - } - return + return + }, } diff --git a/app/cmd/config_list_test.go b/app/cmd/config_list_test.go index e1b702bd895c7b6319cd507cc515605a05555f3b..b1fca4eed63c49174adb6f3f2dcc76790e4b377f 100644 --- a/app/cmd/config_list_test.go +++ b/app/cmd/config_list_test.go @@ -25,6 +25,7 @@ var _ = Describe("config list command", func() { }) AfterEach(func() { + config = nil rootCmd.SetArgs([]string{}) os.Remove(rootOptions.ConfigFile) rootOptions.ConfigFile = "" @@ -43,8 +44,8 @@ var _ = Describe("config list command", func() { rootCmd.SetArgs([]string{"config", "list"}) _, err = rootCmd.ExecuteC() Expect(err).To(BeNil()) - Expect(buf.String()).To(Equal(`number name url description -0 *yourServer http://localhost:8080/jenkins + Expect(buf.String()).To(Equal(`Name URL Description +yourServer http://localhost:8080/jenkins `)) }) @@ -61,9 +62,77 @@ var _ = Describe("config list command", func() { rootCmd.SetArgs([]string{"config", "list"}) _, err = rootCmd.ExecuteC() Expect(err).To(BeNil()) - Expect(buf.String()).To(Equal(`number name url description -0 *yourServer http://localhost:8080/jenkins 012345678901234 + Expect(buf.String()).To(Equal(`Name URL Description +yourServer http://localhost:8080/jenkins 01234567890123456789 `)) }) + + It("print the list of PreHooks", func() { + sampleConfig := getSampleConfig() + config = &sampleConfig + + buf := new(bytes.Buffer) + rootCmd.SetOutput(buf) + rootCmd.SetArgs([]string{"config", "list", "--config", "PreHooks"}) + _, err := rootCmd.ExecuteC() + Expect(err).To(BeNil()) + Expect(buf.String()).To(Equal(`Path Command +`)) + }) + + It("print the list of PostHooks", func() { + sampleConfig := getSampleConfig() + config = &sampleConfig + + buf := new(bytes.Buffer) + rootCmd.SetOutput(buf) + rootCmd.SetArgs([]string{"config", "list", "--config", "PostHooks"}) + _, err := rootCmd.ExecuteC() + Expect(err).To(BeNil()) + Expect(buf.String()).To(Equal(`Path Command +`)) + }) + + It("print the list of Mirrors", func() { + sampleConfig := getSampleConfig() + config = &sampleConfig + + buf := new(bytes.Buffer) + rootCmd.SetOutput(buf) + rootCmd.SetArgs([]string{"config", "list", "--config", "Mirrors"}) + _, err := rootCmd.ExecuteC() + Expect(err).To(BeNil()) + Expect(buf.String()).To(Equal(`Name URL +default http://mirrors.jenkins.io/ +tsinghua https://mirrors.tuna.tsinghua.edu.cn/jenkins/ +huawei https://mirrors.huaweicloud.com/jenkins/ +tencent https://mirrors.cloud.tencent.com/jenkins/ +`)) + }) + + It("print the list of PluginSuites", func() { + sampleConfig := getSampleConfig() + config = &sampleConfig + + buf := new(bytes.Buffer) + rootCmd.SetOutput(buf) + rootCmd.SetArgs([]string{"config", "list", "--config", "PluginSuites"}) + _, err := rootCmd.ExecuteC() + Expect(err).To(BeNil()) + Expect(buf.String()).To(Equal(`Name Description +`)) + }) + + It("print the list of a fake type", func() { + sampleConfig := getSampleConfig() + config = &sampleConfig + + buf := new(bytes.Buffer) + rootCmd.SetOutput(buf) + rootCmd.SetArgs([]string{"config", "list", "--config", "fake"}) + _, err := rootCmd.ExecuteC() + Expect(err).To(HaveOccurred()) + Expect(buf.String()).To(ContainSubstring("unknow config")) + }) }) }) diff --git a/app/cmd/credential_list.go b/app/cmd/credential_list.go index 52895650bf6723300d0a837bd41e928b90b0aa32..d5fdacf5cea040418a243d1fc2fadf4c5fb2949b 100644 --- a/app/cmd/credential_list.go +++ b/app/cmd/credential_list.go @@ -1,15 +1,12 @@ package cmd import ( - "bytes" - "fmt" "net/http" "github.com/jenkins-zh/jenkins-cli/client" "github.com/jenkins-zh/jenkins-cli/app/i18n" - "github.com/jenkins-zh/jenkins-cli/util" "github.com/spf13/cobra" ) @@ -28,7 +25,7 @@ func init() { credentialCmd.AddCommand(credentialListCmd) credentialListCmd.Flags().StringVarP(&credentialListOption.Store, "store", "", "system", i18n.T("The store name of Jenkins credentials")) - credentialListOption.SetFlag(credentialListCmd) + credentialListOption.SetFlagWithHeaders(credentialListCmd, "DisplayName,ID,TypeName,Description") } var credentialListCmd = &cobra.Command{ @@ -44,11 +41,9 @@ var credentialListCmd = &cobra.Command{ getCurrentJenkinsAndClient(&(jClient.JenkinsCore)) var credentialList client.CredentialList - var data []byte if credentialList, err = jClient.GetList(credentialListOption.Store); err == nil { - if data, err = credentialListOption.Output(credentialList); err == nil { - cmd.Print(string(data)) - } + credentialListOption.Writer = cmd.OutOrStdout() + err = credentialListOption.OutputV2(credentialList.Credentials) } return }, @@ -56,21 +51,3 @@ var credentialListCmd = &cobra.Command{ since: "v0.0.24", }, } - -// Output render data into byte array as a table format -func (o *CredentialListOption) Output(obj interface{}) (data []byte, err error) { - if data, err = o.OutputOption.Output(obj); err != nil && o.Format == TableOutputFormat { - credentialList := obj.(client.CredentialList) - - buf := new(bytes.Buffer) - table := util.CreateTableWithHeader(buf, o.WithoutHeaders) - table.AddHeader("number", "displayName", "id", "type", "description") - for i, cred := range credentialList.Credentials { - table.AddRow(fmt.Sprintf("%d", i), cred.DisplayName, cred.ID, cred.TypeName, cred.Description) - } - table.Render() - err = nil - data = buf.Bytes() - } - return -} diff --git a/app/cmd/credential_list_test.go b/app/cmd/credential_list_test.go index 4182be3e9e5f786b5c54b2f8fbda903ca767b835..7e560545d903e5d2597b98c088e5f1af1b46861d 100644 --- a/app/cmd/credential_list_test.go +++ b/app/cmd/credential_list_test.go @@ -63,8 +63,8 @@ var _ = Describe("credential list command", func() { rootCmd.SetArgs([]string{"credential", "list"}) _, err = rootCmd.ExecuteC() Expect(err).To(BeNil()) - Expect(buf.String()).To(Equal(`number displayName id type description -0 displayName 19c27487-acca-4a39-9889-9ddd500388f3 Username with password + Expect(buf.String()).To(Equal(`DisplayName ID TypeName Description +displayName 19c27487-acca-4a39-9889-9ddd500388f3 Username with password `)) }) }) diff --git a/app/cmd/job_history.go b/app/cmd/job_history.go index 9268cab57eceb832e39d92e20aca6baf70d1172c..06dc92664a0b13c84adf56454e6be3a176b7e094 100644 --- a/app/cmd/job_history.go +++ b/app/cmd/job_history.go @@ -1,8 +1,6 @@ package cmd import ( - "bytes" - "fmt" "net/http" "github.com/jenkins-zh/jenkins-cli/app/i18n" @@ -22,7 +20,7 @@ var jobHistoryOption JobHistoryOption func init() { jobCmd.AddCommand(jobHistoryCmd) - jobHistoryOption.SetFlag(jobHistoryCmd) + jobHistoryOption.SetFlagWithHeaders(jobHistoryCmd, "DisplayName,Building,Result") } var jobHistoryCmd = &cobra.Command{ @@ -43,44 +41,26 @@ var jobHistoryCmd = &cobra.Command{ var builds []*client.JobBuild builds, err = jClient.GetHistory(jobName) if err == nil { - var data []byte - data, err = jobHistoryOption.Output(builds) - if err == nil && len(data) > 0 { - cmd.Print(string(data)) + jobHistoryOption.Writer = cmd.OutOrStdout() + jobHistoryOption.CellRenderMap = map[string]RenderCell{ + "Result": ColorResult, } + err = jobHistoryOption.OutputV2(builds) } return }, } -// Output print the output -func (o *JobHistoryOption) Output(obj interface{}) (data []byte, err error) { - if data, err = o.OutputOption.Output(obj); err != nil { - buildList := obj.([]*client.JobBuild) - buf := new(bytes.Buffer) - table := util.CreateTable(buf) - table.AddRow("number", "displayname", "building", "result") - for i, build := range buildList { - table.AddRow(fmt.Sprintf("%d", i), build.DisplayName, - fmt.Sprintf("%v", build.Building), ColorResult(build.Result)) - } - table.Render() - data = buf.Bytes() - err = nil - } - return -} - // ColorResult output the result with color -func ColorResult(result string) string { - switch result { +func ColorResult(cell string) string { + switch cell { case "": return "" case "SUCCESS": - return util.ColorInfo(result) + return util.ColorInfo(cell) case "FAILURE": - return util.ColorError(result) + return util.ColorError(cell) default: - return util.ColorWarning(result) + return util.ColorWarning(cell) } } diff --git a/app/cmd/job_history_test.go b/app/cmd/job_history_test.go index dc65b65b03c99fcc83c26e087aa3f3c00e2bf0e1..c6e696aa15d102c400fb3c34a4b3ff30b65337dd 100644 --- a/app/cmd/job_history_test.go +++ b/app/cmd/job_history_test.go @@ -68,9 +68,9 @@ var _ = Describe("job history command", func() { _, err = rootCmd.ExecuteC() Expect(err).To(BeNil()) - Expect(buf.String()).To(Equal(`number displayname building result -0 fake false -1 fake false + Expect(buf.String()).To(Equal(`DisplayName Building Result +fake false +fake false `)) }) }) diff --git a/app/cmd/job_search.go b/app/cmd/job_search.go index 61a60cbc2af2d53222fb9a2dc468235d96ed07c5..9e6da2124df37126c8cbddc580f95ad0d72d5ea6 100644 --- a/app/cmd/job_search.go +++ b/app/cmd/job_search.go @@ -32,11 +32,7 @@ func init() { i18n.T("The name of plugin for search")) jobSearchCmd.Flags().StringVarP(&jobSearchOption.Type, "type", "", "", i18n.T("The type of plugin for search")) - jobSearchCmd.Flags().StringVarP(&jobSearchOption.Columns, "columns", "", "Name,DisplayName,Type,URL", - i18n.T("The columns of table")) - jobSearchCmd.Flags().StringArrayVarP(&jobSearchOption.Filter, "filter", "", []string{}, - i18n.T("Filter for the list")) - jobSearchOption.SetFlag(jobSearchCmd) + jobSearchOption.SetFlagWithHeaders(jobSearchCmd, "Name,DisplayName,Type,URL") healthCheckRegister.Register(getCmdPath(jobSearchCmd), &jobSearchOption) } diff --git a/app/cmd/plugin_list.go b/app/cmd/plugin_list.go index 01b5b5705f017a400f3abab576e0ade58f9e92a2..ec19143a79a445c36cc11d007d827cab15f85b04 100644 --- a/app/cmd/plugin_list.go +++ b/app/cmd/plugin_list.go @@ -1,24 +1,16 @@ package cmd import ( - "bytes" - "fmt" - "github.com/jenkins-zh/jenkins-cli/app/helper" "github.com/jenkins-zh/jenkins-cli/app/i18n" - "net/http" - "strings" - "github.com/jenkins-zh/jenkins-cli/client" - "github.com/jenkins-zh/jenkins-cli/util" "github.com/spf13/cobra" + "net/http" ) // PluginListOption option for plugin list command type PluginListOption struct { OutputOption - Filter []string - RoundTripper http.RoundTripper } @@ -26,8 +18,7 @@ var pluginListOption PluginListOption func init() { pluginCmd.AddCommand(pluginListCmd) - pluginListCmd.Flags().StringArrayVarP(&pluginListOption.Filter, "filter", "", []string{}, "Filter for the list, like: active, hasUpdate, downgradable, enable, name=foo") - pluginListOption.SetFlag(pluginListCmd) + pluginListOption.SetFlagWithHeaders(pluginListCmd, "ShortName,Version,HasUpdate") } var pluginListCmd = &cobra.Command{ @@ -37,95 +28,19 @@ var pluginListCmd = &cobra.Command{ Example: ` jcli plugin list --filter name=github jcli plugin list --filter hasUpdate jcli plugin list --no-headers`, - Run: func(cmd *cobra.Command, _ []string) { - jclient := &client.PluginManager{ + RunE: func(cmd *cobra.Command, _ []string) (err error) { + jClient := &client.PluginManager{ JenkinsCore: client.JenkinsCore{ RoundTripper: pluginListOption.RoundTripper, }, } - getCurrentJenkinsAndClientOrDie(&(jclient.JenkinsCore)) - - var ( - filter bool - hasUpdate bool - downgradable bool - enable bool - active bool - pluginName string - ) - if pluginListOption.Filter != nil { - filter = true - for _, f := range pluginListOption.Filter { - switch f { - case "hasUpdate": - hasUpdate = true - case "downgradable": - downgradable = true - case "enable": - enable = true - case "active": - active = true - } + getCurrentJenkinsAndClientOrDie(&(jClient.JenkinsCore)) - if strings.HasPrefix(f, "name=") { - pluginName = strings.TrimPrefix(f, "name=") - } - } - } - - var err error var plugins *client.InstalledPluginList - if plugins, err = jclient.GetPlugins(1); err == nil { - filteredPlugins := make([]client.InstalledPlugin, 0) - for _, plugin := range plugins.Plugins { - if filter { - if hasUpdate && !plugin.HasUpdate { - continue - } - - if downgradable && !plugin.Downgradable { - continue - } - - if enable && !plugin.Enable { - continue - } - - if active && !plugin.Active { - continue - } - - if pluginName != "" && !strings.Contains(plugin.ShortName, pluginName) { - continue - } - - filteredPlugins = append(filteredPlugins, plugin) - } - } - - var data []byte - if data, err = pluginListOption.Output(filteredPlugins); err == nil && len(data) > 0 { - cmd.Print(string(data)) - } + if plugins, err = jClient.GetPlugins(1); err == nil { + pluginListOption.Writer = cmd.OutOrStdout() + err = pluginListOption.OutputV2(plugins.Plugins) } - helper.CheckErr(cmd, err) + return }, } - -// Output render data into byte array as a table format -func (o *PluginListOption) Output(obj interface{}) (data []byte, err error) { - if data, err = o.OutputOption.Output(obj); err != nil && o.Format == TableOutputFormat { - buf := new(bytes.Buffer) - - pluginList := obj.([]client.InstalledPlugin) - table := util.CreateTableWithHeader(buf, o.WithoutHeaders) - table.AddHeader("number", "name", "version", "update") - for i, plugin := range pluginList { - table.AddRow(fmt.Sprintf("%d", i), plugin.ShortName, plugin.Version, fmt.Sprintf("%v", plugin.HasUpdate)) - } - table.Render() - err = nil - data = buf.Bytes() - } - return -} diff --git a/app/cmd/plugin_list_test.go b/app/cmd/plugin_list_test.go index f94df7f3be1c9e5848ecc54c5137e7acdd449dd6..74c18bb7240f141efafc9c58dc30aa195bcbf743 100644 --- a/app/cmd/plugin_list_test.go +++ b/app/cmd/plugin_list_test.go @@ -52,7 +52,7 @@ var _ = Describe("plugin list command", func() { _, err = rootCmd.ExecuteC() Expect(err).To(BeNil()) - Expect(buf.String()).To(Equal("number name version update\n")) + Expect(buf.String()).To(Equal("ShortName Version HasUpdate\n")) }) It("one plugin in the list", func() { @@ -71,8 +71,8 @@ var _ = Describe("plugin list command", func() { _, err = rootCmd.ExecuteC() Expect(err).To(BeNil()) - Expect(buf.String()).To(Equal(`number name version update -0 fake 1.0 true + Expect(buf.String()).To(Equal(`ShortName Version HasUpdate +fake 1.0 true `)) }) @@ -92,7 +92,7 @@ var _ = Describe("plugin list command", func() { _, err = rootCmd.ExecuteC() Expect(err).To(BeNil()) - Expect(buf.String()).To(Equal(`0 fake 1.0 true + Expect(buf.String()).To(Equal(`fake 1.0 true `)) }) @@ -105,7 +105,8 @@ var _ = Describe("plugin list command", func() { request, _ := client.PrepareForOneInstalledPlugin(roundTripper, "http://localhost:8080/jenkins") request.SetBasicAuth("admin", "111e3a2f0231198855dceaff96f20540a9") - rootCmd.SetArgs([]string{"plugin", "list", "fake", "--output", "json", "--filter", "hasUpdate", "--filter", "name=fake", "--filter", "enable", "--filter", "active"}) + rootCmd.SetArgs([]string{"plugin", "list", "fake", "--output", "json", "--filter", "HasUpdate=true", + "--filter", "ShortName=fake", "--filter", "Enable=true", "--filter", "Active=true"}) buf := new(bytes.Buffer) rootCmd.SetOutput(buf) @@ -124,7 +125,8 @@ var _ = Describe("plugin list command", func() { request, _ := client.PrepareForOneInstalledPlugin(roundTripper, "http://localhost:8080/jenkins") request.SetBasicAuth("admin", "111e3a2f0231198855dceaff96f20540a9") - rootCmd.SetArgs([]string{"plugin", "list", "fake", "--output", "yaml", "--filter", "hasUpdate", "--filter", "name=fake", "--filter", "enable", "--filter", "active"}) + rootCmd.SetArgs([]string{"plugin", "list", "fake", "--output", "yaml", "--filter", "HasUpdate=true", + "--filter", "Name=fake", "--filter", "Enable=true", "--filter", "Active=true"}) buf := new(bytes.Buffer) rootCmd.SetOutput(buf) @@ -145,12 +147,10 @@ var _ = Describe("plugin list command", func() { rootCmd.SetArgs([]string{"plugin", "list", "fake", "--output", "fake"}) - buf := new(bytes.Buffer) - rootCmd.SetOutput(buf) _, err = rootCmd.ExecuteC() - Expect(err).To(BeNil()) + Expect(err).To(HaveOccurred()) - Expect(buf.String()).To(Equal("error: not support format fake")) + Expect(err.Error()).To(ContainSubstring("not support format fake")) }) }) }) diff --git a/app/cmd/queue_list.go b/app/cmd/queue_list.go index 66fca6a2ebd3826facd927bf4b837e1079bb9daa..0fbb653285a53c4b04ef0595abc871b9dc9d3089 100644 --- a/app/cmd/queue_list.go +++ b/app/cmd/queue_list.go @@ -1,13 +1,9 @@ package cmd import ( - "bytes" - "fmt" - "github.com/jenkins-zh/jenkins-cli/util" + "github.com/jenkins-zh/jenkins-cli/app/i18n" "net/http" - "github.com/jenkins-zh/jenkins-cli/app/helper" - "github.com/jenkins-zh/jenkins-cli/client" "github.com/spf13/cobra" ) @@ -23,48 +19,27 @@ var queueListOption QueueListOption func init() { queueCmd.AddCommand(queueListCmd) - queueListOption.SetFlag(queueListCmd) + queueListOption.SetFlagWithHeaders(queueListCmd, "ID,Why,URL") } var queueListCmd = &cobra.Command{ Use: "list", - Short: "Print the queue of your Jenkins", - Long: `Print the queue of your Jenkins`, - Run: func(cmd *cobra.Command, _ []string) { - jclient := &client.QueueClient{ + Short: i18n.T("Print the queue of your Jenkins"), + Long: i18n.T("Print the queue of your Jenkins"), + RunE: func(cmd *cobra.Command, _ []string) (err error) { + jClient := &client.QueueClient{ JenkinsCore: client.JenkinsCore{ RoundTripper: queueListOption.RoundTripper, Debug: rootOptions.Debug, }, } - getCurrentJenkinsAndClientOrDie(&(jclient.JenkinsCore)) + getCurrentJenkinsAndClientOrDie(&(jClient.JenkinsCore)) - var err error var jobQueue *client.JobQueue - if jobQueue, err = jclient.Get(); err == nil { - var data []byte - if data, err = queueListOption.Output(jobQueue); err == nil && len(data) > 0 { - cmd.Print(string(data)) - } + if jobQueue, err = jClient.Get(); err == nil { + queueListOption.Writer = cmd.OutOrStdout() + err = queueListOption.OutputV2(jobQueue.Items) } - helper.CheckErr(cmd, err) + return }, } - -// Output render data into byte array as a table format -func (o *QueueListOption) Output(obj interface{}) (data []byte, err error) { - if data, err = o.OutputOption.Output(obj); err != nil && o.Format == TableOutputFormat { - buf := new(bytes.Buffer) - - jobQueue := obj.(*client.JobQueue) - table := util.CreateTableWithHeader(buf, o.WithoutHeaders) - table.AddHeader("number", "id", "why", "url") - for i, item := range jobQueue.Items { - table.AddRow(fmt.Sprintf("%d", i), fmt.Sprintf("%d", item.ID), item.Why, item.URL) - } - table.Render() - err = nil - data = buf.Bytes() - } - return -} diff --git a/app/cmd/queue_list_test.go b/app/cmd/queue_list_test.go index 411870fc7382f36467ad75698d025918a4994a93..54cb2f769a72721b89f0123dd376ed8eb330e3c7 100644 --- a/app/cmd/queue_list_test.go +++ b/app/cmd/queue_list_test.go @@ -53,24 +53,21 @@ var _ = Describe("queue list command", func() { rootCmd.SetOutput(buf) _, err = rootCmd.ExecuteC() Expect(err).To(BeNil()) - - Expect(buf.String()).To(Equal(`{ - "Items": [ - { - "Blocked": false, - "Buildable": true, - "ID": 62, - "Params": "", - "Pending": false, - "Stuck": true, - "URL": "queue/item/62/", - "Why": "等待下一个可用的执行器", - "BuildableStartMilliseconds": 1567753826770, - "InQueueSince": 1567753826770, - "Actions": [] - } - ] -}`)) + Expect(buf.String()).To(Equal(`[ + { + "Blocked": false, + "Buildable": true, + "ID": 62, + "Params": "", + "Pending": false, + "Stuck": true, + "URL": "queue/item/62/", + "Why": "等待下一个可用的执行器", + "BuildableStartMilliseconds": 1567753826770, + "InQueueSince": 1567753826770, + "Actions": [] + } +]`)) }) It("output with table format", func() { @@ -88,8 +85,8 @@ var _ = Describe("queue list command", func() { _, err = rootCmd.ExecuteC() Expect(err).To(BeNil()) - Expect(buf.String()).To(Equal(`number id why url -0 62 等待下一个可用的执行器 queue/item/62/ + Expect(buf.String()).To(Equal(`ID Why URL +62 等待下一个可用的执行器 queue/item/62/ `)) }) }) diff --git a/client/computer_test.go b/client/computer_test.go index a575ed94fff38f838486a78cfd7a77bf5dff504d..6d7be39ae664518cbff5940ae43f705dfcc08ec7 100644 --- a/client/computer_test.go +++ b/client/computer_test.go @@ -34,7 +34,7 @@ var _ = Describe("computer test", func() { computers, err := computerClient.List() Expect(err).NotTo(HaveOccurred()) Expect(computers).NotTo(BeNil()) - Expect(len(computers.Computer)).To(Equal(1)) + Expect(len(computers.Computer)).To(Equal(2)) }) It("Launch", func() { diff --git a/client/computer_test_common.go b/client/computer_test_common.go index 0b227607f266246efd8b0cfe17c93099e1dc309c..e9256a619abca49b49ab6532ec38eaa06e204ce7 100644 --- a/client/computer_test_common.go +++ b/client/computer_test_common.go @@ -58,6 +58,7 @@ func PrepareForComputerList() string { "_class" : "hudson.model.ComputerSet", "busyExecutors" : 1, "computer" : [ + {"offline" : true}, { "_class" : "hudson.model.Hudson$MasterComputer", "actions" : [