/
open.go
135 lines (119 loc) · 3.64 KB
/
open.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package cmd
import (
"fmt"
"github.com/jenkins-zh/jenkins-cli/app/cmd/common"
appCfg "github.com/jenkins-zh/jenkins-cli/app/config"
"github.com/jenkins-zh/jenkins-cli/app/i18n"
"github.com/jenkins-zh/jenkins-cli/util"
"github.com/spf13/cobra"
"go.uber.org/zap"
"os"
"os/exec"
"strings"
"syscall"
)
// OpenOption is the open cmd option
type OpenOption struct {
common.Option
common.InteractiveOption
Browser string
Config bool
}
var openOption OpenOption
func init() {
rootCmd.AddCommand(openCmd)
openCmd.Flags().BoolVarP(&openOption.Config, "config", "c", false,
i18n.T("Open the configuration page of Jenkins"))
openCmd.Flags().StringVarP(&openOption.Browser, "browser", "b", "",
i18n.T("Open Jenkins with a specific browser"))
openOption.SetFlag(openCmd)
openOption.Stdio = common.GetSystemStdio()
err := openCmd.RegisterFlagCompletionFunc("browser", func(cmd *cobra.Command, args []string, toComplete string) (strings []string, directive cobra.ShellCompDirective) {
return []string{"Google-Chrome", "Safari", "Microsoft-Edge", "Firefox"}, cobra.ShellCompDirectiveDefault
})
if err != nil {
rootCmd.Println(err)
}
}
var openCmd = &cobra.Command{
Use: "open",
Short: i18n.T("Open your Jenkins with a browser"),
Long: i18n.T(`Open your Jenkins with a browser`),
ValidArgsFunction: ValidJenkinsAndDataNames,
Example: `jcli open -n [config name]
Open Jenkins with a specific browser is useful in some use cases. For example, one browser has a proxy setting.
There are two ways to achieve this:
jcli open --browser "Google-Chrome"
JCLI_BROWSER="Google Chrome" jcli open`,
PreRun: func(_ *cobra.Command, _ []string) {
if openOption.Browser == "" {
openOption.Browser = os.Getenv("JCLI_BROWSER")
}
},
RunE: openOption.run,
}
func (o *OpenOption) run(_ *cobra.Command, args []string) (err error) {
var jenkins *appCfg.JenkinsServer
var configName string
if len(args) > 0 {
configName = args[0]
}
if configName == "" && o.Interactive {
jenkinsNames := getJenkinsNames()
configName, err = o.Select(jenkinsNames,
i18n.T("Choose a Jenkins which you want to open:"), "")
}
jenkinsName, external := o.parseName(configName)
logger.Info("open jenkins",
zap.String("jenkins name", jenkinsName),
zap.String("external", external))
if err == nil {
if jenkinsName != "" {
jenkins = findJenkinsByName(jenkinsName)
} else {
jenkins = getCurrentJenkins()
}
if jenkins != nil && jenkins.URL != "" {
url := jenkins.URL
if o.Config {
url = fmt.Sprintf("%s/configure", url)
} else if external != "" {
url = jenkins.Data[external]
}
err = o.smartOpen(url)
} else {
err = fmt.Errorf("no URL found with Jenkins %s", jenkinsName)
}
}
return
}
// smartOpen can open with or without specific protocol
func (o *OpenOption) smartOpen(url string) (err error) {
var cmd string
if strings.HasPrefix(url, "ssh://") {
if cmd, err = exec.LookPath("ssh"); err == nil {
err = syscall.Exec(cmd, []string{"ssh", strings.TrimLeft(url, "ssh://")}, os.Environ())
}
} else if strings.HasPrefix(url, "shell://") {
shellCmd := strings.TrimLeft(url, "shell://")
shellArgs := strings.Split(shellCmd, " ")
if cmd, err = exec.LookPath(shellArgs[0]); err == nil {
err = syscall.Exec(cmd, shellArgs, os.Environ())
}
} else {
browser := o.Browser
err = util.Open(url, browser, o.ExecContext)
}
return
}
// parseName the string expect likes name or name.external
func (o *OpenOption) parseName(configName string) (jenkins, external string) {
array := strings.SplitN(configName, ".", 2)
if len(array) > 0 {
jenkins = array[0]
}
if len(array) > 1 {
external = array[1]
}
return
}