未验证 提交 099e99b4 编写于 作者: LinuxSuRen's avatar LinuxSuRen 提交者: GitHub

Improve the data output from cmd (#285)

* Improve the data output from cmd

* Improve the data output of credential list

* Improve the data output of computer and job history list

* Improve list output of config list

* Add more computer list test cases

* Improve the output of queue

* Remove unused imports
上级 1cc95bfa
...@@ -3,6 +3,7 @@ package cmd ...@@ -3,6 +3,7 @@ package cmd
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"go.uber.org/zap"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
"io" "io"
"net/http" "net/http"
...@@ -36,9 +37,13 @@ type OutputOption struct { ...@@ -36,9 +37,13 @@ type OutputOption struct {
WithoutHeaders bool WithoutHeaders bool
Filter []string 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 // FormatOutput is the interface of format output
type FormatOutput interface { type FormatOutput interface {
Output(obj interface{}, format string) (data []byte, err error) Output(obj interface{}, format string) (data []byte, err error)
...@@ -78,6 +83,7 @@ func (o *OutputOption) OutputV2(obj interface{}) (err error) { ...@@ -78,6 +83,7 @@ func (o *OutputOption) OutputV2(obj interface{}) (err error) {
return return
} }
logger.Debug("start to output", zap.Any("filter", o.Filter))
obj = o.ListFilter(obj) obj = o.ListFilter(obj)
var data []byte var data []byte
...@@ -150,17 +156,38 @@ func (o *OutputOption) Match(item reflect.Value) bool { ...@@ -150,17 +156,38 @@ func (o *OutputOption) Match(item reflect.Value) bool {
func (o *OutputOption) GetLine(obj reflect.Value) []string { func (o *OutputOption) GetLine(obj reflect.Value) []string {
columns := strings.Split(o.Columns, ",") columns := strings.Split(o.Columns, ",")
values := make([]string, 0) values := make([]string, 0)
if o.CellRenderMap == nil {
o.CellRenderMap = make(map[string]RenderCell, 0)
}
for _, col := range columns { 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 return values
} }
// SetFlag set flag of output format // SetFlag set flag of output format
// Deprecated, see also SetFlagWithHeaders
func (o *OutputOption) SetFlag(cmd *cobra.Command) { 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, 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 // BatchOption represent the options for a batch operation
......
package cmd package cmd
import ( import (
"bytes"
"fmt"
"net/http" "net/http"
"github.com/jenkins-zh/jenkins-cli/client" "github.com/jenkins-zh/jenkins-cli/client"
...@@ -24,7 +22,7 @@ var computerListOption ComputerListOption ...@@ -24,7 +22,7 @@ var computerListOption ComputerListOption
func init() { func init() {
computerCmd.AddCommand(computerListCmd) computerCmd.AddCommand(computerListCmd)
computerListOption.SetFlag(computerListCmd) computerListOption.SetFlagWithHeaders(computerListCmd, "DisplayName,NumExecutors,Description,Offline")
} }
var computerListCmd = &cobra.Command{ var computerListCmd = &cobra.Command{
...@@ -41,39 +39,18 @@ var computerListCmd = &cobra.Command{ ...@@ -41,39 +39,18 @@ var computerListCmd = &cobra.Command{
var computers client.ComputerList var computers client.ComputerList
if computers, err = jClient.List(); err == nil { if computers, err = jClient.List(); err == nil {
var data []byte computerListOption.Writer = cmd.OutOrStdout()
data, err = computerListOption.Output(computers.Computer) computerListOption.CellRenderMap = map[string]RenderCell{
if err == nil && len(data) > 0 { "Offline": func(offline string) string {
cmd.Print(string(data)) switch offline {
case "true":
return util.ColorWarning("yes")
}
return "no"
},
} }
err = computerListOption.OutputV2(computers.Computer)
} }
return 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"
}
package cmd package cmd
import ( import (
"bytes"
"fmt" "fmt"
"github.com/jenkins-zh/jenkins-cli/app/helper"
"github.com/jenkins-zh/jenkins-cli/app/i18n" "github.com/jenkins-zh/jenkins-cli/app/i18n"
"github.com/jenkins-zh/jenkins-cli/util"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// ConfigListOption option for config list command // ConfigListOption option for config list command
type ConfigListOption struct { type ConfigListOption struct {
OutputOption OutputOption
Config string
} }
var configListOption ConfigListOption var configListOption ConfigListOption
func init() { func init() {
configCmd.AddCommand(configListCmd) 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{ var configListCmd = &cobra.Command{
Use: "list", Use: "list",
Short: i18n.T("List all Jenkins config items"), Short: i18n.T("List all Jenkins config items"),
Long: i18n.T("List all Jenkins config items"), Long: i18n.T("List all Jenkins config items"),
Run: func(cmd *cobra.Command, _ []string) { RunE: func(cmd *cobra.Command, _ []string) (err error) {
current := getCurrentJenkins() configListOption.Writer = cmd.OutOrStdout()
data, err := configListOption.Output(current) switch configListOption.Config {
cmd.Print(string(data)) case "JenkinsServers":
helper.CheckErr(cmd, err) err = configListOption.OutputV2(getConfig().JenkinsServers)
}, case "PreHooks":
} configListOption.Columns = "Path,Command"
err = configListOption.OutputV2(getConfig().PreHooks)
// Output render data into byte array as a table format case "PostHooks":
func (o *ConfigListOption) Output(obj interface{}) (data []byte, err error) { configListOption.Columns = "Path,Command"
if data, err = o.OutputOption.Output(obj); err != nil && o.Format == TableOutputFormat { err = configListOption.OutputV2(getConfig().PostHooks)
current := obj.(*JenkinsServer) case "Mirrors":
configListOption.Columns = "Name,URL"
buf := new(bytes.Buffer) err = configListOption.OutputV2(getConfig().Mirrors)
table := util.CreateTableWithHeader(buf, o.WithoutHeaders) case "PluginSuites":
table.AddHeader("number", "name", "url", "description") configListOption.Columns = "Name,Description"
for i, jenkins := range getConfig().JenkinsServers { err = configListOption.OutputV2(getConfig().PluginSuites)
name := jenkins.Name default:
if name == current.Name { err = fmt.Errorf("unknow config %s", configListOption.Config)
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)
} }
table.Render() return
err = nil },
data = buf.Bytes()
}
return
} }
...@@ -25,6 +25,7 @@ var _ = Describe("config list command", func() { ...@@ -25,6 +25,7 @@ var _ = Describe("config list command", func() {
}) })
AfterEach(func() { AfterEach(func() {
config = nil
rootCmd.SetArgs([]string{}) rootCmd.SetArgs([]string{})
os.Remove(rootOptions.ConfigFile) os.Remove(rootOptions.ConfigFile)
rootOptions.ConfigFile = "" rootOptions.ConfigFile = ""
...@@ -43,8 +44,8 @@ var _ = Describe("config list command", func() { ...@@ -43,8 +44,8 @@ var _ = Describe("config list command", func() {
rootCmd.SetArgs([]string{"config", "list"}) rootCmd.SetArgs([]string{"config", "list"})
_, err = rootCmd.ExecuteC() _, err = rootCmd.ExecuteC()
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(buf.String()).To(Equal(`number name url description Expect(buf.String()).To(Equal(`Name URL Description
0 *yourServer http://localhost:8080/jenkins yourServer http://localhost:8080/jenkins
`)) `))
}) })
...@@ -61,9 +62,77 @@ var _ = Describe("config list command", func() { ...@@ -61,9 +62,77 @@ var _ = Describe("config list command", func() {
rootCmd.SetArgs([]string{"config", "list"}) rootCmd.SetArgs([]string{"config", "list"})
_, err = rootCmd.ExecuteC() _, err = rootCmd.ExecuteC()
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(buf.String()).To(Equal(`number name url description Expect(buf.String()).To(Equal(`Name URL Description
0 *yourServer http://localhost:8080/jenkins 012345678901234 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"))
})
}) })
}) })
package cmd package cmd
import ( import (
"bytes"
"fmt"
"net/http" "net/http"
"github.com/jenkins-zh/jenkins-cli/client" "github.com/jenkins-zh/jenkins-cli/client"
"github.com/jenkins-zh/jenkins-cli/app/i18n" "github.com/jenkins-zh/jenkins-cli/app/i18n"
"github.com/jenkins-zh/jenkins-cli/util"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
...@@ -28,7 +25,7 @@ func init() { ...@@ -28,7 +25,7 @@ func init() {
credentialCmd.AddCommand(credentialListCmd) credentialCmd.AddCommand(credentialListCmd)
credentialListCmd.Flags().StringVarP(&credentialListOption.Store, "store", "", "system", credentialListCmd.Flags().StringVarP(&credentialListOption.Store, "store", "", "system",
i18n.T("The store name of Jenkins credentials")) i18n.T("The store name of Jenkins credentials"))
credentialListOption.SetFlag(credentialListCmd) credentialListOption.SetFlagWithHeaders(credentialListCmd, "DisplayName,ID,TypeName,Description")
} }
var credentialListCmd = &cobra.Command{ var credentialListCmd = &cobra.Command{
...@@ -44,11 +41,9 @@ var credentialListCmd = &cobra.Command{ ...@@ -44,11 +41,9 @@ var credentialListCmd = &cobra.Command{
getCurrentJenkinsAndClient(&(jClient.JenkinsCore)) getCurrentJenkinsAndClient(&(jClient.JenkinsCore))
var credentialList client.CredentialList var credentialList client.CredentialList
var data []byte
if credentialList, err = jClient.GetList(credentialListOption.Store); err == nil { if credentialList, err = jClient.GetList(credentialListOption.Store); err == nil {
if data, err = credentialListOption.Output(credentialList); err == nil { credentialListOption.Writer = cmd.OutOrStdout()
cmd.Print(string(data)) err = credentialListOption.OutputV2(credentialList.Credentials)
}
} }
return return
}, },
...@@ -56,21 +51,3 @@ var credentialListCmd = &cobra.Command{ ...@@ -56,21 +51,3 @@ var credentialListCmd = &cobra.Command{
since: "v0.0.24", 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
}
...@@ -63,8 +63,8 @@ var _ = Describe("credential list command", func() { ...@@ -63,8 +63,8 @@ var _ = Describe("credential list command", func() {
rootCmd.SetArgs([]string{"credential", "list"}) rootCmd.SetArgs([]string{"credential", "list"})
_, err = rootCmd.ExecuteC() _, err = rootCmd.ExecuteC()
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(buf.String()).To(Equal(`number displayName id type description Expect(buf.String()).To(Equal(`DisplayName ID TypeName Description
0 displayName 19c27487-acca-4a39-9889-9ddd500388f3 Username with password displayName 19c27487-acca-4a39-9889-9ddd500388f3 Username with password
`)) `))
}) })
}) })
......
package cmd package cmd
import ( import (
"bytes"
"fmt"
"net/http" "net/http"
"github.com/jenkins-zh/jenkins-cli/app/i18n" "github.com/jenkins-zh/jenkins-cli/app/i18n"
...@@ -22,7 +20,7 @@ var jobHistoryOption JobHistoryOption ...@@ -22,7 +20,7 @@ var jobHistoryOption JobHistoryOption
func init() { func init() {
jobCmd.AddCommand(jobHistoryCmd) jobCmd.AddCommand(jobHistoryCmd)
jobHistoryOption.SetFlag(jobHistoryCmd) jobHistoryOption.SetFlagWithHeaders(jobHistoryCmd, "DisplayName,Building,Result")
} }
var jobHistoryCmd = &cobra.Command{ var jobHistoryCmd = &cobra.Command{
...@@ -43,44 +41,26 @@ var jobHistoryCmd = &cobra.Command{ ...@@ -43,44 +41,26 @@ var jobHistoryCmd = &cobra.Command{
var builds []*client.JobBuild var builds []*client.JobBuild
builds, err = jClient.GetHistory(jobName) builds, err = jClient.GetHistory(jobName)
if err == nil { if err == nil {
var data []byte jobHistoryOption.Writer = cmd.OutOrStdout()
data, err = jobHistoryOption.Output(builds) jobHistoryOption.CellRenderMap = map[string]RenderCell{
if err == nil && len(data) > 0 { "Result": ColorResult,
cmd.Print(string(data))
} }
err = jobHistoryOption.OutputV2(builds)
} }
return 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 // ColorResult output the result with color
func ColorResult(result string) string { func ColorResult(cell string) string {
switch result { switch cell {
case "": case "":
return "" return ""
case "SUCCESS": case "SUCCESS":
return util.ColorInfo(result) return util.ColorInfo(cell)
case "FAILURE": case "FAILURE":
return util.ColorError(result) return util.ColorError(cell)
default: default:
return util.ColorWarning(result) return util.ColorWarning(cell)
} }
} }
...@@ -68,9 +68,9 @@ var _ = Describe("job history command", func() { ...@@ -68,9 +68,9 @@ var _ = Describe("job history command", func() {
_, err = rootCmd.ExecuteC() _, err = rootCmd.ExecuteC()
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(buf.String()).To(Equal(`number displayname building result Expect(buf.String()).To(Equal(`DisplayName Building Result
0 fake false fake false
1 fake false fake false
`)) `))
}) })
}) })
......
...@@ -32,11 +32,7 @@ func init() { ...@@ -32,11 +32,7 @@ func init() {
i18n.T("The name of plugin for search")) i18n.T("The name of plugin for search"))
jobSearchCmd.Flags().StringVarP(&jobSearchOption.Type, "type", "", "", jobSearchCmd.Flags().StringVarP(&jobSearchOption.Type, "type", "", "",
i18n.T("The type of plugin for search")) i18n.T("The type of plugin for search"))
jobSearchCmd.Flags().StringVarP(&jobSearchOption.Columns, "columns", "", "Name,DisplayName,Type,URL", jobSearchOption.SetFlagWithHeaders(jobSearchCmd, "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)
healthCheckRegister.Register(getCmdPath(jobSearchCmd), &jobSearchOption) healthCheckRegister.Register(getCmdPath(jobSearchCmd), &jobSearchOption)
} }
......
package cmd package cmd
import ( 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/app/i18n"
"net/http"
"strings"
"github.com/jenkins-zh/jenkins-cli/client" "github.com/jenkins-zh/jenkins-cli/client"
"github.com/jenkins-zh/jenkins-cli/util"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"net/http"
) )
// PluginListOption option for plugin list command // PluginListOption option for plugin list command
type PluginListOption struct { type PluginListOption struct {
OutputOption OutputOption
Filter []string
RoundTripper http.RoundTripper RoundTripper http.RoundTripper
} }
...@@ -26,8 +18,7 @@ var pluginListOption PluginListOption ...@@ -26,8 +18,7 @@ var pluginListOption PluginListOption
func init() { func init() {
pluginCmd.AddCommand(pluginListCmd) pluginCmd.AddCommand(pluginListCmd)
pluginListCmd.Flags().StringArrayVarP(&pluginListOption.Filter, "filter", "", []string{}, "Filter for the list, like: active, hasUpdate, downgradable, enable, name=foo") pluginListOption.SetFlagWithHeaders(pluginListCmd, "ShortName,Version,HasUpdate")
pluginListOption.SetFlag(pluginListCmd)
} }
var pluginListCmd = &cobra.Command{ var pluginListCmd = &cobra.Command{
...@@ -37,95 +28,19 @@ var pluginListCmd = &cobra.Command{ ...@@ -37,95 +28,19 @@ var pluginListCmd = &cobra.Command{
Example: ` jcli plugin list --filter name=github Example: ` jcli plugin list --filter name=github
jcli plugin list --filter hasUpdate jcli plugin list --filter hasUpdate
jcli plugin list --no-headers`, jcli plugin list --no-headers`,
Run: func(cmd *cobra.Command, _ []string) { RunE: func(cmd *cobra.Command, _ []string) (err error) {
jclient := &client.PluginManager{ jClient := &client.PluginManager{
JenkinsCore: client.JenkinsCore{ JenkinsCore: client.JenkinsCore{
RoundTripper: pluginListOption.RoundTripper, RoundTripper: pluginListOption.RoundTripper,
}, },
} }
getCurrentJenkinsAndClientOrDie(&(jclient.JenkinsCore)) 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
}
if strings.HasPrefix(f, "name=") {
pluginName = strings.TrimPrefix(f, "name=")
}
}
}
var err error
var plugins *client.InstalledPluginList var plugins *client.InstalledPluginList
if plugins, err = jclient.GetPlugins(1); err == nil { if plugins, err = jClient.GetPlugins(1); err == nil {
filteredPlugins := make([]client.InstalledPlugin, 0) pluginListOption.Writer = cmd.OutOrStdout()
for _, plugin := range plugins.Plugins { err = pluginListOption.OutputV2(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))
}
} }
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
}
...@@ -52,7 +52,7 @@ var _ = Describe("plugin list command", func() { ...@@ -52,7 +52,7 @@ var _ = Describe("plugin list command", func() {
_, err = rootCmd.ExecuteC() _, err = rootCmd.ExecuteC()
Expect(err).To(BeNil()) 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() { It("one plugin in the list", func() {
...@@ -71,8 +71,8 @@ var _ = Describe("plugin list command", func() { ...@@ -71,8 +71,8 @@ var _ = Describe("plugin list command", func() {
_, err = rootCmd.ExecuteC() _, err = rootCmd.ExecuteC()
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(buf.String()).To(Equal(`number name version update Expect(buf.String()).To(Equal(`ShortName Version HasUpdate
0 fake 1.0 true fake 1.0 true
`)) `))
}) })
...@@ -92,7 +92,7 @@ var _ = Describe("plugin list command", func() { ...@@ -92,7 +92,7 @@ var _ = Describe("plugin list command", func() {
_, err = rootCmd.ExecuteC() _, err = rootCmd.ExecuteC()
Expect(err).To(BeNil()) 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() { ...@@ -105,7 +105,8 @@ var _ = Describe("plugin list command", func() {
request, _ := client.PrepareForOneInstalledPlugin(roundTripper, "http://localhost:8080/jenkins") request, _ := client.PrepareForOneInstalledPlugin(roundTripper, "http://localhost:8080/jenkins")
request.SetBasicAuth("admin", "111e3a2f0231198855dceaff96f20540a9") 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) buf := new(bytes.Buffer)
rootCmd.SetOutput(buf) rootCmd.SetOutput(buf)
...@@ -124,7 +125,8 @@ var _ = Describe("plugin list command", func() { ...@@ -124,7 +125,8 @@ var _ = Describe("plugin list command", func() {
request, _ := client.PrepareForOneInstalledPlugin(roundTripper, "http://localhost:8080/jenkins") request, _ := client.PrepareForOneInstalledPlugin(roundTripper, "http://localhost:8080/jenkins")
request.SetBasicAuth("admin", "111e3a2f0231198855dceaff96f20540a9") 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) buf := new(bytes.Buffer)
rootCmd.SetOutput(buf) rootCmd.SetOutput(buf)
...@@ -145,12 +147,10 @@ var _ = Describe("plugin list command", func() { ...@@ -145,12 +147,10 @@ var _ = Describe("plugin list command", func() {
rootCmd.SetArgs([]string{"plugin", "list", "fake", "--output", "fake"}) rootCmd.SetArgs([]string{"plugin", "list", "fake", "--output", "fake"})
buf := new(bytes.Buffer)
rootCmd.SetOutput(buf)
_, err = rootCmd.ExecuteC() _, 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"))
}) })
}) })
}) })
......
package cmd package cmd
import ( import (
"bytes" "github.com/jenkins-zh/jenkins-cli/app/i18n"
"fmt"
"github.com/jenkins-zh/jenkins-cli/util"
"net/http" "net/http"
"github.com/jenkins-zh/jenkins-cli/app/helper"
"github.com/jenkins-zh/jenkins-cli/client" "github.com/jenkins-zh/jenkins-cli/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
...@@ -23,48 +19,27 @@ var queueListOption QueueListOption ...@@ -23,48 +19,27 @@ var queueListOption QueueListOption
func init() { func init() {
queueCmd.AddCommand(queueListCmd) queueCmd.AddCommand(queueListCmd)
queueListOption.SetFlag(queueListCmd) queueListOption.SetFlagWithHeaders(queueListCmd, "ID,Why,URL")
} }
var queueListCmd = &cobra.Command{ var queueListCmd = &cobra.Command{
Use: "list", Use: "list",
Short: "Print the queue of your Jenkins", Short: i18n.T("Print the queue of your Jenkins"),
Long: `Print the queue of your Jenkins`, Long: i18n.T("Print the queue of your Jenkins"),
Run: func(cmd *cobra.Command, _ []string) { RunE: func(cmd *cobra.Command, _ []string) (err error) {
jclient := &client.QueueClient{ jClient := &client.QueueClient{
JenkinsCore: client.JenkinsCore{ JenkinsCore: client.JenkinsCore{
RoundTripper: queueListOption.RoundTripper, RoundTripper: queueListOption.RoundTripper,
Debug: rootOptions.Debug, Debug: rootOptions.Debug,
}, },
} }
getCurrentJenkinsAndClientOrDie(&(jclient.JenkinsCore)) getCurrentJenkinsAndClientOrDie(&(jClient.JenkinsCore))
var err error
var jobQueue *client.JobQueue var jobQueue *client.JobQueue
if jobQueue, err = jclient.Get(); err == nil { if jobQueue, err = jClient.Get(); err == nil {
var data []byte queueListOption.Writer = cmd.OutOrStdout()
if data, err = queueListOption.Output(jobQueue); err == nil && len(data) > 0 { err = queueListOption.OutputV2(jobQueue.Items)
cmd.Print(string(data))
}
} }
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
}
...@@ -53,24 +53,21 @@ var _ = Describe("queue list command", func() { ...@@ -53,24 +53,21 @@ var _ = Describe("queue list command", func() {
rootCmd.SetOutput(buf) rootCmd.SetOutput(buf)
_, err = rootCmd.ExecuteC() _, err = rootCmd.ExecuteC()
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(buf.String()).To(Equal(`[
Expect(buf.String()).To(Equal(`{ {
"Items": [ "Blocked": false,
{ "Buildable": true,
"Blocked": false, "ID": 62,
"Buildable": true, "Params": "",
"ID": 62, "Pending": false,
"Params": "", "Stuck": true,
"Pending": false, "URL": "queue/item/62/",
"Stuck": true, "Why": "等待下一个可用的执行器",
"URL": "queue/item/62/", "BuildableStartMilliseconds": 1567753826770,
"Why": "等待下一个可用的执行器", "InQueueSince": 1567753826770,
"BuildableStartMilliseconds": 1567753826770, "Actions": []
"InQueueSince": 1567753826770, }
"Actions": [] ]`))
}
]
}`))
}) })
It("output with table format", func() { It("output with table format", func() {
...@@ -88,8 +85,8 @@ var _ = Describe("queue list command", func() { ...@@ -88,8 +85,8 @@ var _ = Describe("queue list command", func() {
_, err = rootCmd.ExecuteC() _, err = rootCmd.ExecuteC()
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(buf.String()).To(Equal(`number id why url Expect(buf.String()).To(Equal(`ID Why URL
0 62 等待下一个可用的执行器 queue/item/62/ 62 等待下一个可用的执行器 queue/item/62/
`)) `))
}) })
}) })
......
...@@ -34,7 +34,7 @@ var _ = Describe("computer test", func() { ...@@ -34,7 +34,7 @@ var _ = Describe("computer test", func() {
computers, err := computerClient.List() computers, err := computerClient.List()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(computers).NotTo(BeNil()) Expect(computers).NotTo(BeNil())
Expect(len(computers.Computer)).To(Equal(1)) Expect(len(computers.Computer)).To(Equal(2))
}) })
It("Launch", func() { It("Launch", func() {
......
...@@ -58,6 +58,7 @@ func PrepareForComputerList() string { ...@@ -58,6 +58,7 @@ func PrepareForComputerList() string {
"_class" : "hudson.model.ComputerSet", "_class" : "hudson.model.ComputerSet",
"busyExecutors" : 1, "busyExecutors" : 1,
"computer" : [ "computer" : [
{"offline" : true},
{ {
"_class" : "hudson.model.Hudson$MasterComputer", "_class" : "hudson.model.Hudson$MasterComputer",
"actions" : [ "actions" : [
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册