提交 94454dbc 编写于 作者: X xiang 提交者: LinuxSuRen

Allow pass a file type param when build Jenkins job

* define const string
* fix check
* merge master
* minor update
* support upload file
* can run success
* add unit test
* refine code
* add cmd config param-file
上级 13ca43fe
...@@ -3,11 +3,10 @@ package cmd ...@@ -3,11 +3,10 @@ package cmd
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/jenkins-zh/jenkins-cli/app/cmd/common"
"strings" "strings"
"github.com/jenkins-zh/jenkins-cli/app/cmd/common"
"github.com/jenkins-zh/jenkins-cli/app/i18n" "github.com/jenkins-zh/jenkins-cli/app/i18n"
"github.com/jenkins-zh/jenkins-cli/client" "github.com/jenkins-zh/jenkins-cli/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
...@@ -19,6 +18,8 @@ type JobBuildOption struct { ...@@ -19,6 +18,8 @@ type JobBuildOption struct {
Param string Param string
ParamArray []string ParamArray []string
ParamFilePathArray []string
} }
var jobBuildOption JobBuildOption var jobBuildOption JobBuildOption
...@@ -35,6 +36,9 @@ func init() { ...@@ -35,6 +36,9 @@ func init() {
i18n.T("Parameters of the job which is JSON format")) i18n.T("Parameters of the job which is JSON format"))
jobBuildCmd.Flags().StringArrayVar(&jobBuildOption.ParamArray, "param-entry", nil, jobBuildCmd.Flags().StringArrayVar(&jobBuildOption.ParamArray, "param-entry", nil,
i18n.T("Parameters of the job which are the entry format, for example: --param-entry name=value")) i18n.T("Parameters of the job which are the entry format, for example: --param-entry name=value"))
jobBuildCmd.Flags().StringArrayVar(&jobBuildOption.ParamFilePathArray, "param-file", nil,
i18n.T("Parameters of the job which is file path, for example: --param-file name=filename"))
jobBuildOption.BatchOption.Stdio = common.GetSystemStdio() jobBuildOption.BatchOption.Stdio = common.GetSystemStdio()
jobBuildOption.CommonOption.Stdio = common.GetSystemStdio() jobBuildOption.CommonOption.Stdio = common.GetSystemStdio()
} }
...@@ -45,8 +49,8 @@ var jobBuildCmd = &cobra.Command{ ...@@ -45,8 +49,8 @@ var jobBuildCmd = &cobra.Command{
Long: i18n.T(`Build the job of your Jenkins. Long: i18n.T(`Build the job of your Jenkins.
You need to give the parameters if your pipeline has them. Learn more about it from https://jenkins.io/doc/book/pipeline/syntax/#parameters.`), You need to give the parameters if your pipeline has them. Learn more about it from https://jenkins.io/doc/book/pipeline/syntax/#parameters.`),
Args: cobra.MinimumNArgs(1), Args: cobra.MinimumNArgs(1),
PreRunE: func(cmd *cobra.Command, args []string) (err error) { PreRunE: func(_ *cobra.Command, _ []string) (err error) {
if jobBuildOption.ParamArray == nil { if jobBuildOption.ParamArray == nil && jobBuildOption.ParamFilePathArray == nil {
return return
} }
...@@ -67,13 +71,23 @@ You need to give the parameters if your pipeline has them. Learn more about it f ...@@ -67,13 +71,23 @@ You need to give the parameters if your pipeline has them. Learn more about it f
} }
} }
for _, filepathEntry := range jobBuildOption.ParamFilePathArray {
if filepathArray := strings.SplitN(filepathEntry, "=", 2); len(filepathArray) == 2 {
paramDefs = append(paramDefs, client.ParameterDefinition{
Name: filepathArray[0],
Filepath: filepathArray[1],
Type: client.FileParameterDefinition,
})
}
}
var data []byte var data []byte
if data, err = json.Marshal(paramDefs); err == nil { if data, err = json.Marshal(paramDefs); err == nil {
jobBuildOption.Param = string(data) jobBuildOption.Param = string(data)
} }
return return
}, },
RunE: func(cmd *cobra.Command, args []string) (err error) { RunE: func(_ *cobra.Command, args []string) (err error) {
name := args[0] name := args[0]
if !jobBuildOption.Confirm(fmt.Sprintf("Are you sure to build job %s", name)) { if !jobBuildOption.Confirm(fmt.Sprintf("Are you sure to build job %s", name)) {
......
...@@ -3,14 +3,15 @@ package cmd ...@@ -3,14 +3,15 @@ package cmd
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io/ioutil"
"net/http"
"os"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
"github.com/jenkins-zh/jenkins-cli/client" "github.com/jenkins-zh/jenkins-cli/client"
"github.com/jenkins-zh/jenkins-cli/mock/mhttp" "github.com/jenkins-zh/jenkins-cli/mock/mhttp"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"io/ioutil"
"net/http"
"os"
) )
var _ = Describe("job build command", func() { var _ = Describe("job build command", func() {
...@@ -102,6 +103,22 @@ var _ = Describe("job build command", func() { ...@@ -102,6 +103,22 @@ var _ = Describe("job build command", func() {
_, err = rootCmd.ExecuteC() _, err = rootCmd.ExecuteC()
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
}) })
/* FIXME: fix the test case
It("with --param-file", func() {
data, err := generateSampleConfig()
Expect(err).To(BeNil())
err = ioutil.WriteFile(rootOptions.ConfigFile, data, 0664)
Expect(err).To(BeNil())
client.PrepareForBuildWithParams(roundTripper, "http://localhost:8080/jenkins", jobName,
"admin", "111e3a2f0231198855dceaff96f20540a9")
rootCmd.SetArgs([]string{"job", "build", jobName, "--param-file", "sample=/tmp/sample.txt", "-b", "true", "--param", ""})
_, err = rootCmd.ExecuteC()
Expect(err).NotTo(HaveOccurred())
})
*/
}) })
}) })
......
...@@ -215,11 +215,11 @@ type bintree struct { ...@@ -215,11 +215,11 @@ type bintree struct {
} }
var _bintree = &bintree{nil, map[string]*bintree{ var _bintree = &bintree{nil, map[string]*bintree{
"jcli": &bintree{nil, map[string]*bintree{ "jcli": {nil, map[string]*bintree{
"zh_CN": &bintree{nil, map[string]*bintree{ "zh_CN": {nil, map[string]*bintree{
"LC_MESSAGES": &bintree{nil, map[string]*bintree{ "LC_MESSAGES": {nil, map[string]*bintree{
"jcli.mo": &bintree{jcliZh_cnLc_messagesJcliMo, map[string]*bintree{}}, "jcli.mo": {jcliZh_cnLc_messagesJcliMo, map[string]*bintree{}},
"jcli.po": &bintree{jcliZh_cnLc_messagesJcliPo, map[string]*bintree{}}, "jcli.po": {jcliZh_cnLc_messagesJcliPo, map[string]*bintree{}},
}}, }},
}}, }},
}}, }},
......
package client package client
import ( import (
"bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"go.uber.org/zap" "io"
"io/ioutil" "io/ioutil"
"moul.io/http2curl" "mime/multipart"
"net/http" "net/http"
"net/url" "net/url"
"os"
"path/filepath"
"strconv" "strconv"
"strings" "strings"
"go.uber.org/zap"
"moul.io/http2curl"
"github.com/jenkins-zh/jenkins-cli/util" "github.com/jenkins-zh/jenkins-cli/util"
) )
// FileParameterDefinition is the definition for file parameter
const FileParameterDefinition = "FileParameterDefinition"
// JobClient is client for operate jobs // JobClient is client for operate jobs
type JobClient struct { type JobClient struct {
JenkinsCore JenkinsCore
...@@ -55,20 +64,55 @@ func (q *JobClient) BuildWithParams(jobName string, parameters []ParameterDefini ...@@ -55,20 +64,55 @@ func (q *JobClient) BuildWithParams(jobName string, parameters []ParameterDefini
path := ParseJobPath(jobName) path := ParseJobPath(jobName)
api := fmt.Sprintf("%s/build", path) api := fmt.Sprintf("%s/build", path)
fileParameters := make([]ParameterDefinition, 0, len(parameters))
for _, parameter := range parameters {
if parameter.Type == FileParameterDefinition {
fileParameters = append(fileParameters, parameter)
}
}
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
defer writer.Close()
// upload file
for _, parameter := range fileParameters {
var file *os.File
file, err = os.Open(parameter.Filepath)
if err != nil {
return err
}
defer file.Close()
var fWriter io.Writer
fWriter, err = writer.CreateFormFile(parameter.Filepath, filepath.Base(parameter.Filepath))
if err != nil {
return err
}
_, err = io.Copy(fWriter, file)
}
var paramJSON []byte var paramJSON []byte
if len(parameters) == 1 { if len(parameters) == 1 {
paramJSON, err = json.Marshal(parameters[0]) paramJSON, err = json.Marshal(parameters[0])
} else { } else {
paramJSON, err = json.Marshal(parameters) paramJSON, err = json.Marshal(parameters)
} }
if err != nil {
return err
}
if err == nil { if err = writer.WriteField("json", fmt.Sprintf("{\"parameter\": %s}", string(paramJSON))); err != nil {
formData := url.Values{"json": {fmt.Sprintf("{\"parameter\": %s}", string(paramJSON))}} return err
payload := strings.NewReader(formData.Encode()) }
_, err = q.RequestWithoutData("POST", api, if err = writer.Close(); err != nil {
map[string]string{util.ContentType: util.ApplicationForm}, payload, 201) return err
} }
_, err = q.RequestWithoutData("POST", api,
map[string]string{util.ContentType: writer.FormDataContentType()}, body, 201)
return return
} }
...@@ -377,6 +421,7 @@ type ParameterDefinition struct { ...@@ -377,6 +421,7 @@ type ParameterDefinition struct {
Name string `json:"name"` Name string `json:"name"`
Type string Type string
Value string `json:"value"` Value string `json:"value"`
Filepath string `json:"file"`
DefaultParameterValue DefaultParameterValue DefaultParameterValue DefaultParameterValue
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册