job_edit.go 3.9 KB
Newer Older
LinuxSuRen's avatar
LinuxSuRen 已提交
1 2 3
package cmd

import (
4 5
	"encoding/base64"
	"fmt"
6
	"github.com/jenkins-zh/jenkins-cli/app/i18n"
7
	"github.com/jenkins-zh/jenkins-cli/client"
LinuxSuRen's avatar
LinuxSuRen 已提交
8
	"github.com/spf13/cobra"
9 10 11
	"io/ioutil"
	"net/http"
	"regexp"
LinuxSuRen's avatar
LinuxSuRen 已提交
12 13
)

14 15
// JobEditOption is the option for job create command
type JobEditOption struct {
16 17
	CommonOption

18 19 20 21 22
	Filename  string
	Script    string
	URL       string
	Sample    bool
	TrimSpace bool
23 24 25 26
}

var jobEditOption JobEditOption

LinuxSuRen's avatar
LinuxSuRen 已提交
27 28
func init() {
	jobCmd.AddCommand(jobEditCmd)
29
	jobEditCmd.Flags().StringVarP(&jobEditOption.URL, "url", "", "",
LinuxSuRen's avatar
LinuxSuRen 已提交
30
		i18n.T("URL of the Jenkinsfile to files to use to replace pipeline"))
31
	jobEditCmd.Flags().StringVarP(&jobEditOption.Filename, "filename", "f", "",
LinuxSuRen's avatar
LinuxSuRen 已提交
32
		i18n.T("Filename to files to use to replace pipeline"))
33
	jobEditCmd.Flags().StringVarP(&jobEditOption.Script, "script", "s", "",
LinuxSuRen's avatar
LinuxSuRen 已提交
34
		i18n.T("Script to use to replace pipeline. Use script first if you give filename at the meantime."))
35 36
	jobEditCmd.Flags().BoolVarP(&jobEditOption.Sample, "sample", "", false,
		i18n.T("Give it a sample Jenkinsfile if the target script is empty"))
37 38
	jobEditCmd.Flags().BoolVarP(&jobEditOption.TrimSpace, "trim", "", true,
		i18n.T("If trim the leading and tailing white space"))
39
	jobEditOption.Stdio = GetSystemStdio()
LinuxSuRen's avatar
LinuxSuRen 已提交
40 41 42
}

var jobEditCmd = &cobra.Command{
43
	Use:   "edit",
LinuxSuRen's avatar
LinuxSuRen 已提交
44
	Short: i18n.T("Edit the job of your Jenkins"),
45 46 47 48 49
	Long: i18n.T(fmt.Sprintf(`Edit the job of your Jenkins. We only support to edit the pipeline job.
Official Pipeline syntax document is here https://jenkins.io/doc/book/pipeline/syntax/

%s`, GetEditorHelpText())),
	Args: cobra.MinimumNArgs(1),
LinuxSuRen's avatar
LinuxSuRen 已提交
50
	RunE: func(cmd *cobra.Command, args []string) (err error) {
LinuxSuRen's avatar
LinuxSuRen 已提交
51
		name := args[0]
LinuxSuRen's avatar
LinuxSuRen 已提交
52 53
		var content string

54 55 56 57
		jclient := &client.JobClient{
			JenkinsCore: client.JenkinsCore{
				RoundTripper: jobEditOption.RoundTripper,
			},
LinuxSuRen's avatar
LinuxSuRen 已提交
58
		}
59
		getCurrentJenkinsAndClientOrDie(&(jclient.JenkinsCore))
LinuxSuRen's avatar
LinuxSuRen 已提交
60

LinuxSuRen's avatar
LinuxSuRen 已提交
61
		if content, err = jobEditOption.getPipeline(jclient, name); err == nil {
62 63 64
			if jobEditOption.TrimSpace {
				content = regexp.MustCompile("^\\W+|\\s+$").ReplaceAllString(content, "")
			}
LinuxSuRen's avatar
LinuxSuRen 已提交
65
			err = jclient.UpdatePipeline(name, content)
LinuxSuRen's avatar
LinuxSuRen 已提交
66
		}
LinuxSuRen's avatar
LinuxSuRen 已提交
67
		return
LinuxSuRen's avatar
LinuxSuRen 已提交
68 69 70
	},
}

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
func (j *JobEditOption) getSampleJenkinsfile() string {
	return `pipeline {
    agent {
		    label 'master'
	  }
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
    post { 
        always { 
            echo 'I will always say Hello again!'
        }
    }
}
`
}

92 93 94 95 96 97 98 99 100 101 102
//func getPipeline(name string) (script string, err error) {
func (j *JobEditOption) getPipeline(jClient *client.JobClient, name string) (script string, err error) {
	script = j.Script //we take the script from input firstly
	if script != "" {
		return
	}

	// take script from a file
	if script, err = j.getPipelineFromFile(); script != "" || err != nil {
		return
	}
LinuxSuRen's avatar
LinuxSuRen 已提交
103

104 105 106 107
	if script, err = j.getPipelineFromURL(jClient); script != "" || err != nil {
		return
	}

LinuxSuRen's avatar
LinuxSuRen 已提交
108
	var job *client.Pipeline
109 110 111 112 113
	if job, err = jClient.GetPipeline(name); err == nil {
		content := ""
		if job != nil {
			content = job.Script
		}
114 115 116 117 118 119 120

		// if the original script is empty, give it a sample script
		if content == "" && j.Sample {
			content = j.getSampleJenkinsfile()
		}

		j.EditFileName = fmt.Sprintf("Jenkinsfile.%s.groovy", base64.StdEncoding.EncodeToString([]byte(name)))
121
		script, err = j.Editor(content, "Edit your pipeline script")
122 123 124 125 126 127 128 129 130 131 132 133
	}
	return
}

func (j *JobEditOption) getPipelineFromFile() (script string, err error) {
	if j.Filename == "" {
		return
	}

	var data []byte
	if data, err = ioutil.ReadFile(j.Filename); err == nil {
		script = string(data)
LinuxSuRen's avatar
LinuxSuRen 已提交
134 135 136
	}
	return
}
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152

func (j *JobEditOption) getPipelineFromURL(jClient *client.JobClient) (script string, err error) {
	if j.URL == "" {
		return
	}

	var resp *http.Response
	var body []byte
	httpClient := jClient.JenkinsCore.GetClient()
	if resp, err = httpClient.Get(j.URL); err == nil {
		if body, err = ioutil.ReadAll(resp.Body); err == nil {
			script = string(body)
		}
	}
	return
}