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

Add support to output installed plugins as json format (#137)

* Add support to output installed plugins as json format

* Fix the wrong filter of plugin list

* Adjust the test data

* Adjust the test data
上级 dae8ec17
......@@ -4,8 +4,8 @@ import (
"encoding/json"
"fmt"
"github.com/jenkins-zh/jenkins-cli/client"
"github.com/AlecAivazis/survey/v2"
"github.com/jenkins-zh/jenkins-cli/client"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
)
......@@ -36,8 +36,9 @@ func (o *OutputOption) Output(obj interface{}) (data []byte, err error) {
return nil, fmt.Errorf("not support format %s", o.Format)
}
// SetFlag set flag of output format
func (o *OutputOption) SetFlag(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.Format, "output", "o", "table", "Format the output (default 'json')")
cmd.Flags().StringVarP(&o.Format, "output", "o", "table", "Format the output, supported formats: table, json, yaml")
}
func Format(obj interface{}, format string) (data []byte, err error) {
......
package cmd
import (
"bytes"
"fmt"
"log"
"os"
"net/http"
"strings"
"github.com/jenkins-zh/jenkins-cli/client"
......@@ -11,10 +12,13 @@ import (
"github.com/spf13/cobra"
)
// PluginListOption option for plugin list command
type PluginListOption struct {
OutputOption
Filter []string
RoundTripper http.RoundTripper
}
var pluginListOption PluginListOption
......@@ -22,6 +26,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)
}
var pluginListCmd = &cobra.Command{
......@@ -30,14 +35,13 @@ var pluginListCmd = &cobra.Command{
Long: `Print all the plugins which are installed`,
Example: ` jcli plugin list --filter name=github
jcli plugin list --filter hasUpdate`,
Run: func(_ *cobra.Command, _ []string) {
jenkins := getCurrentJenkinsFromOptionsOrDie()
jclient := &client.PluginManager{}
jclient.URL = jenkins.URL
jclient.UserName = jenkins.UserName
jclient.Token = jenkins.Token
jclient.Proxy = jenkins.Proxy
jclient.ProxyAuth = jenkins.ProxyAuth
Run: func(cmd *cobra.Command, _ []string) {
jclient := &client.PluginManager{
JenkinsCore: client.JenkinsCore{
RoundTripper: pluginListOption.RoundTripper,
},
}
getCurrentJenkinsAndClient(&(jclient.JenkinsCore))
var (
filter bool
......@@ -59,8 +63,6 @@ var pluginListCmd = &cobra.Command{
enable = true
case "active":
active = true
case "name":
downgradable = true
}
if strings.HasPrefix(f, "name=") {
......@@ -99,7 +101,7 @@ var pluginListCmd = &cobra.Command{
if data, err := pluginListOption.Output(filteredPlugins); err == nil {
if len(data) > 0 {
fmt.Println(string(data))
cmd.Print(string(data))
}
} else {
log.Fatal(err)
......@@ -110,17 +112,20 @@ var pluginListCmd = &cobra.Command{
},
}
// 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 {
buf := new(bytes.Buffer)
pluginList := obj.([]client.InstalledPlugin)
table := util.CreateTable(os.Stdout)
table := util.CreateTable(buf)
table.AddRow("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 = []byte{}
data = buf.Bytes()
}
return
}
package cmd
import (
"bytes"
"io/ioutil"
"os"
"github.com/golang/mock/gomock"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/jenkins-zh/jenkins-cli/client"
"github.com/jenkins-zh/jenkins-cli/mock/mhttp"
)
var _ = Describe("plugin list command", func() {
var (
ctrl *gomock.Controller
roundTripper *mhttp.MockRoundTripper
)
BeforeEach(func() {
ctrl = gomock.NewController(GinkgoT())
roundTripper = mhttp.NewMockRoundTripper(ctrl)
pluginListOption.RoundTripper = roundTripper
rootCmd.SetArgs([]string{})
rootOptions.Jenkins = ""
rootOptions.ConfigFile = "test.yaml"
})
AfterEach(func() {
rootCmd.SetArgs([]string{})
os.Remove(rootOptions.ConfigFile)
rootOptions.ConfigFile = ""
ctrl.Finish()
})
Context("basic cases", func() {
It("no plugin in the list", func() {
data, err := generateSampleConfig()
Expect(err).To(BeNil())
err = ioutil.WriteFile(rootOptions.ConfigFile, data, 0664)
Expect(err).To(BeNil())
request, _ := client.PrepareForEmptyInstalledPluginList(roundTripper, "http://localhost:8080/jenkins")
request.SetBasicAuth("admin", "111e3a2f0231198855dceaff96f20540a9")
rootCmd.SetArgs([]string{"plugin", "list"})
buf := new(bytes.Buffer)
rootCmd.SetOutput(buf)
_, err = rootCmd.ExecuteC()
Expect(err).To(BeNil())
Expect(buf.String()).To(Equal("number name version update\n"))
})
It("one plugin in the list", func() {
data, err := generateSampleConfig()
Expect(err).To(BeNil())
err = ioutil.WriteFile(rootOptions.ConfigFile, data, 0664)
Expect(err).To(BeNil())
request, _ := client.PrepareForOneInstalledPlugin(roundTripper, "http://localhost:8080/jenkins")
request.SetBasicAuth("admin", "111e3a2f0231198855dceaff96f20540a9")
rootCmd.SetArgs([]string{"plugin", "list", "fake"})
buf := new(bytes.Buffer)
rootCmd.SetOutput(buf)
_, err = rootCmd.ExecuteC()
Expect(err).To(BeNil())
Expect(buf.String()).To(Equal(`number name version update
0 fake 1.0 true
`))
})
It("one plugin output with json format", func() {
data, err := generateSampleConfig()
Expect(err).To(BeNil())
err = ioutil.WriteFile(rootOptions.ConfigFile, data, 0664)
Expect(err).To(BeNil())
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"})
buf := new(bytes.Buffer)
rootCmd.SetOutput(buf)
_, err = rootCmd.ExecuteC()
Expect(err).To(BeNil())
Expect(buf.String()).To(Equal(pluginsJSON()))
})
})
})
func pluginsJSON() string {
return `[
{
"Active": true,
"Enabled": false,
"Bundled": false,
"Downgradable": false,
"Deleted": false,
"Enable": true,
"ShortName": "fake",
"LongName": "",
"Version": "1.0",
"URL": "",
"HasUpdate": true,
"Pinned": false,
"RequiredCoreVesion": "",
"MinimumJavaVersion": "",
"SupportDynamicLoad": "",
"BackVersion": ""
}
]`
}
......@@ -84,26 +84,8 @@ var _ = Describe("PluginManager test", func() {
})
Context("GetPlugins", func() {
var (
api string
)
BeforeEach(func() {
api = fmt.Sprintf("%s/pluginManager/api/json?depth=1", pluginMgr.URL)
})
It("no plugin in the list", func() {
request, _ := http.NewRequest("GET", api, nil)
response := &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString(`{
"plugins": []
}`)),
}
roundTripper.EXPECT().
RoundTrip(request).Return(response, nil)
PrepareForEmptyInstalledPluginList(roundTripper, pluginMgr.URL)
pluginList, err := pluginMgr.GetPlugins()
Expect(err).To(BeNil())
......@@ -112,19 +94,7 @@ var _ = Describe("PluginManager test", func() {
})
It("one plugin in the list", func() {
request, _ := http.NewRequest("GET", api, nil)
response := &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString(`{
"plugins": [{
"shortName": "fake"
}]
}`)),
}
roundTripper.EXPECT().
RoundTrip(request).Return(response, nil)
PrepareForOneInstalledPlugin(roundTripper, pluginMgr.URL)
pluginList, err := pluginMgr.GetPlugins()
Expect(err).To(BeNil())
......@@ -134,15 +104,7 @@ var _ = Describe("PluginManager test", func() {
})
It("response with 500", func() {
request, _ := http.NewRequest("GET", api, nil)
response := &http.Response{
StatusCode: 500,
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString("")),
}
roundTripper.EXPECT().
RoundTrip(request).Return(response, nil)
PrepareFor500InstalledPluginList(roundTripper, pluginMgr.URL)
_, err := pluginMgr.GetPlugins()
Expect(err).To(HaveOccurred())
......
......@@ -47,3 +47,44 @@ func PrepareForOneAvaiablePlugin(roundTripper *mhttp.MockRoundTripper, rootURL s
RoundTrip(request).Return(response, nil)
return
}
// PrepareForEmptyInstalledPluginList only for test
func PrepareForEmptyInstalledPluginList(roundTripper *mhttp.MockRoundTripper, rootURL string) (
request *http.Request, response *http.Response) {
request, _ = http.NewRequest("GET", fmt.Sprintf("%s/pluginManager/api/json?depth=1", rootURL), nil)
response = &http.Response{
StatusCode: 200,
Proto: "HTTP/1.1",
Request: request,
Body: ioutil.NopCloser(bytes.NewBufferString(`{
"plugins": []
}`)),
}
roundTripper.EXPECT().
RoundTrip(request).Return(response, nil)
return
}
// PrepareForOneInstalledPlugin only for test
func PrepareForOneInstalledPlugin(roundTripper *mhttp.MockRoundTripper, rootURL string) (
request *http.Request, response *http.Response) {
request, response = PrepareForEmptyInstalledPluginList(roundTripper, rootURL)
response.Body = ioutil.NopCloser(bytes.NewBufferString(`{
"plugins": [{
"shortName": "fake",
"version": "1.0",
"hasUpdate": true,
"enable": true,
"active": true
}]
}`))
return
}
// PrepareFor500InstalledPluginList only for test
func PrepareFor500InstalledPluginList(roundTripper *mhttp.MockRoundTripper, rootURL string) (
request *http.Request, response *http.Response) {
request, response = PrepareForEmptyInstalledPluginList(roundTripper, rootURL)
response.StatusCode = 500
return
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册