diff --git a/Makefile b/Makefile index 62ac681b443191b28ce1a6e04d5cd85fc98d2fbf..9c7555e91ccde24650f0796929896227c540bcd4 100644 --- a/Makefile +++ b/Makefile @@ -1,30 +1,38 @@ BUILD_NAME:=gitmm BIN_DIR:=bin -BUILD_VERSION:=1.0.6 +BUILD_MODE?=snapshot +BUILD_VERSION?=1.1.0 BUILD_DATE:=$(shell date '+%Y%m%d.%H%M%S') SOURCE:=*.go -LDFLAGS:=-ldflags "-X '${BUILD_NAME}/cmd.VERSION=${BUILD_VERSION}-${BUILD_DATE}'" + +ifeq ($(BUILD_MODE),release) +SOFT_VERSION:=${BUILD_VERSION} +else +SOFT_VERSION:="${BUILD_VERSION}-${BUILD_DATE}" +endif + +LDFLAGS:=-ldflags "-X '${BUILD_NAME}/cmd.VERSION=${SOFT_VERSION}'" all:clean build_win package test: clean @echo "test" - @go test + - @go test ./... build_win: test - @echo "build_win" + @echo "build win" @GO111MODULE=on CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build ${LDFLAGS} -o ${BIN_DIR}/${BUILD_NAME}.exe ${SOURCE} -build_unix: test - @echo "build_unix" +build_linux: test + @echo "build linux" @GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ${LDFLAGS} -o ${BIN_DIR}/${BUILD_NAME} ${SOURCE} install_win: clean build_win - @echo "install_win" + @echo "install win" @cp ${BIN_DIR}/${BUILD_NAME}.exe /c/Windows/ -install_unix: clean build_unix - @echo "install_unix" +install_linux: clean build_linux + @echo "install linux" @cp ${BIN_DIR}/${BUILD_NAME} /usr/bin package : @@ -32,7 +40,16 @@ package : @cp README.md ${BIN_DIR} @cp repo.yaml ${BIN_DIR} - @find . -maxdepth 1 -type f -name "${BUILD_NAME}*.tar.gz" -exec rm -f {} \; - @cd ${BIN_DIR} && tar -czf ../${BUILD_NAME}-${BUILD_VERSION}-${BUILD_DATE}.tar.gz * + @cd ${BIN_DIR} && tar -czf ../${BUILD_NAME}-${SOFT_VERSION}.tar.gz * + +release : + @echo "source release" +ifneq ($(BUILD_MODE),release) + @echo "currently started in snapshot mode" +else + @echo "${BUILD_VERSION} will be released" +# @git tag -a ${BUILD_VERSION} +endif clean: @echo "clean" @@ -40,4 +57,4 @@ clean: - @rm -rf ${BIN_DIR} - @find . -maxdepth 1 -type f -name "${BUILD_NAME}*.tar.gz" -exec rm -f {} \; -.PHONY: all test build_win install_win build_unix install_unix package clean \ No newline at end of file +.PHONY: all test build_win install_win build_linux install_linux package clean \ No newline at end of file diff --git a/README.md b/README.md index 1724708f1c7be30c0dc20cbb27021c63a10c39bd..5927d476ea9f62cc2ad102b72e4078b9fe65ed21 100644 --- a/README.md +++ b/README.md @@ -74,10 +74,11 @@ git config --global credential.helper store 配置文件 `repo.yaml` 用来配置主从仓库上游信息,示例内容如下: ```yaml -# upstream from -upstream: "git@gitee.com:chmodke" -# origin to -origin: "ssh://git@192.168.100.100:2222/chmodke" +remote: + # upstream from + upstream: 'git@gitee.com:chmodke' + # origin to + origin: 'ssh://git@192.168.100.100:2222/chmodke' # repos repository list repos: - arpc @@ -110,6 +111,7 @@ Available Commands: config 生成示例配置文件,校验配置文件 create 批量创建分支 help Help about any command + list 展示工作路径下的Git仓库信息 pull 批量拉取仓库 remote 批量查看仓库远程信息 switch 批量切换分支 @@ -154,6 +156,32 @@ gitmm config verify - 无参数 +### list + +> 遍历展示仓库最新提交记录 + +执行命令会遍历`work_dir`目录下中的git仓库,展示仓库最新提交记录。 + +#### 执行格式 + +```shell +Usage: + gitmm list [flags] + +Examples: +gitmm list -w tmp + +Flags: + -h, --help help for list + -i, --invert-match string 仓库反向过滤条件,golang正则表达式 + -n, --line-number int 日志行数 (default 1) + -m, --match string 仓库过滤条件,golang正则表达式 + -w, --work_dir string 本地代码的存放路径 (default ".") + +Global Flags: + -x, --debug string show more detail. (default "info") +``` + ### clone > 批量克隆仓库 @@ -173,9 +201,11 @@ Flags: -h, --help help for clone -i, --invert-match string 仓库反向过滤条件,golang正则表达式 -m, --match string 仓库过滤条件,golang正则表达式 + -u, --remote string 克隆代码的远程名称 (default "origin") -b, --work_branch string 克隆代码的分支 (default "master") -w, --work_dir string 克隆代码的存放路径 (default "master") + Global Flags: -x, --debug string show more detail. (default "info") @@ -185,8 +215,9 @@ gitmm clone -w tmp -b master #### 参数 -- work_dir: 必填项,克隆代码的存放路径 +- work_dir: 可选项,克隆代码的存放路径 - work_branch: 可选项,克隆代码的分支,缺省值`master` +- remote: 可选项,克隆代码的远程名称,缺省值`origin` - match: 可选项,仓库过滤条件,golang正则表达式,优先级高于`invert-match` - invert-match: 可选项,仓库反向过滤条件,golang正则表达式 diff --git a/cmd/clone.go b/cmd/clone.go index 15777385beeb7bad0868c858257aac54b513428c..1e9a64f10dc7c032e8fe00a2ce7c52e52d431a62 100644 --- a/cmd/clone.go +++ b/cmd/clone.go @@ -7,6 +7,7 @@ import ( "gitmm/config" "gitmm/log" "gitmm/util" + "os" ) var cloneCmd = &cobra.Command{ @@ -16,18 +17,27 @@ var cloneCmd = &cobra.Command{ Example: "gitmm clone -w tmp -b master", Run: func(cmd *cobra.Command, args []string) { config.LoadCfg() - log.Debugf("origin: %s", config.Origin) - log.Debugf("repos: %s", config.Repos) workDir, _ := cmd.Flags().GetString("work_dir") log.Debugf("work_dir: %s", workDir) workBranch, _ := cmd.Flags().GetString("work_branch") log.Debugf("work_branch: %s", workBranch) + remote, _ := cmd.Flags().GetString("remote") + log.Debugf("remote: %s", remote) match, _ := cmd.Flags().GetString("match") log.Debugf("match: %s", match) invert, _ := cmd.Flags().GetString("invert-match") log.Debugf("invert: %s", invert) + url, ok := config.Remote[remote] + if !ok { + fmt.Printf("未配置%s远端地址\n", remote) + os.Exit(1) + } + + log.Debugf("remote-url: %s", url) + log.Debugf("repos: %s", config.Repos) + result := make(map[string]string) for _, repo := range config.Repos { if !util.Match(repo, match, invert) { @@ -36,7 +46,7 @@ var cloneCmd = &cobra.Command{ continue } log.Info(util.LeftAlign(fmt.Sprintf("start clone %s.", repo), 2, "-")) - ok := util.GitClone(config.Origin, repo, workDir, workBranch) + ok := util.GitClone(url, repo, remote, workDir, workBranch) if ok { log.Info(util.LeftAlign(fmt.Sprintf("clone %s done.\n", repo), 2, "-")) result[repo] = OK @@ -53,8 +63,8 @@ func init() { rootCmd.AddCommand(cloneCmd) cloneCmd.Flags().StringP("work_dir", "w", "master", "克隆代码的存放路径") - cloneCmd.MarkFlagRequired("work_dir") cloneCmd.Flags().StringP("work_branch", "b", "master", "克隆代码的分支") + cloneCmd.Flags().StringP("remote", "u", "origin", "克隆代码的远程名称") cloneCmd.Flags().StringP("match", "m", "", "仓库过滤条件,golang正则表达式") cloneCmd.Flags().StringP("invert-match", "i", "", "仓库反向过滤条件,golang正则表达式") } diff --git a/cmd/list.go b/cmd/list.go index fac78db1f5e6e23b2a7a34e07e1a59fe3ebb5fd1..a89d3fb2ac58f9fdbaa49d6804e28d54c466531f 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -8,7 +8,6 @@ import ( "gitmm/util" "path/filepath" "strconv" - "strings" ) // listCmd represents the batch command @@ -38,14 +37,14 @@ var listCmd = &cobra.Command{ log.Error("获取本地仓库失败") } - var commands []string - commands = append(commands, "git") - commands = append(commands, "-C %s") - commands = append(commands, "log") - commands = append(commands, "-n"+strconv.Itoa(lineNumber)) - commands = append(commands, "--pretty=\"format:%%ad %%h %%d %%n%%s%%n\"") - commands = append(commands, "--date=iso") - preCmd := strings.Join(commands, " ") + builder := &util.CmdBuilder{} + builder.Add("git") + builder.Add("-C %s") + builder.Add("log") + builder.Add("-n" + strconv.Itoa(lineNumber)) + builder.Add("--pretty=\"format:%%ad %%h %%d %%n%%s%%n\"") + builder.Add("--date=iso") + preCmd := builder.Build() result := make(map[string]string) for _, repo := range repos { diff --git a/cmd/version.go b/cmd/version.go index cdd4804a4906053368d90f087e0022ec97a8c69d..18ff50677ebacaefb458ec3a39f482e4f0f8a657 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -12,7 +12,7 @@ import ( "strings" ) -var VERSION = "1.0.6" +var VERSION = "1.1.0" // versionCmd represents the version command var versionCmd = &cobra.Command{ diff --git a/config/configLoader.go b/config/configLoader.go index fe8b0337d5952525e3b6fab58f2a34b5a7714436..d626ce30f99b6f16e4d9bcbf173d45a1cd1262b8 100644 --- a/config/configLoader.go +++ b/config/configLoader.go @@ -9,6 +9,7 @@ import ( var viperConfig *viper.Viper var ( + Remote map[string]string Origin string Upstream string Repos []string @@ -42,15 +43,23 @@ func LoadCfg() { fmt.Println("可以执行`gitmm config`命令生成示例配置文件。") os.Exit(1) } - Origin = viperConfig.GetString("origin") - Upstream = viperConfig.GetString("upstream") + Remote = viperConfig.GetStringMapString("remote") + var ok = false + if Origin, ok = Remote["origin"]; !ok { + fmt.Println("未配置origin远端地址") + os.Exit(1) + } + if Upstream, ok = Remote["upstream"]; !ok { + fmt.Println("未配置upstream远端地址") + os.Exit(1) + } Repos = viperConfig.GetStringSlice("repos") } func WriteCfg() { sample := viper.New() - sample.Set("upstream", "git@gitee.com:chmodke") - sample.Set("origin", "git@github.com:chmodke") + remote := map[string]string{"upstream": "git@gitee.com:chmodke", "origin": "git@github.com:chmodke"} + sample.Set("remote", remote) sample.Set("repos", []string{"arpc", "ftrans"}) sample.WriteConfigAs("repo_sample.yaml") diff --git a/go.mod b/go.mod index 4b153eba611046097d5e66c10ae1f2c853a058e3..ce166156f09cc7bfa894d30442a601f651d6348e 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.18 require ( github.com/spf13/cobra v1.5.0 github.com/spf13/viper v1.12.0 + golang.org/x/text v0.3.7 ) require ( @@ -21,7 +22,6 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.3.0 // indirect golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect - golang.org/x/text v0.3.7 // indirect gopkg.in/ini.v1 v1.66.4 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/repo.yaml b/repo.yaml index 1bc4cf6db2490f3b709582aecb47030908360572..a84624e21587bfaa24bd653fbb978dea43328c24 100644 --- a/repo.yaml +++ b/repo.yaml @@ -1,5 +1,6 @@ -upstream: "git@gitee.com:chmodke" -origin: "ssh://git@192.168.100.100:2222/chmodke" +remote: + upstream: 'git@gitee.com:chmodke' + origin: 'ssh://git@192.168.100.100:2222/chmodke' repos: - arpc - ftrans diff --git a/util/buildCmd.go b/util/buildCmd.go new file mode 100644 index 0000000000000000000000000000000000000000..5ddff7482c04af708662ef559411408e4649834b --- /dev/null +++ b/util/buildCmd.go @@ -0,0 +1,49 @@ +package util + +import ( + "fmt" + "strings" +) + +type CmdBuilder struct { + commands []string +} + +func (b *CmdBuilder) Add(command string) *CmdBuilder { + b.AddWithCond(command, true) + return b +} + +func (b *CmdBuilder) AddWithArg(command string, args ...interface{}) *CmdBuilder { + b.Add(fmt.Sprintf(command, args...)) + return b +} + +func (b *CmdBuilder) AddWithCond(command string, cond bool) *CmdBuilder { + if cond { + b.commands = append(b.commands, command) + } + return b +} + +func (b *CmdBuilder) AddWithArgAndCond(command string, cond bool, args ...interface{}) *CmdBuilder { + if cond { + b.Add(fmt.Sprintf(command, args...)) + } + return b +} + +func (b *CmdBuilder) Build() string { + if b.commands == nil { + return "" + } + return strings.Join(b.commands, " ") +} + +func (b *CmdBuilder) Reset() *CmdBuilder { + if b.commands == nil { + return b + } + b.commands = b.commands[:0] + return b +} diff --git a/util/buildCmd_test.go b/util/buildCmd_test.go new file mode 100644 index 0000000000000000000000000000000000000000..de25834e16891952f7ba5381c75768228883f64b --- /dev/null +++ b/util/buildCmd_test.go @@ -0,0 +1,81 @@ +package util + +import ( + "testing" +) + +func TestBuildCmd(t *testing.T) { + builder := &CmdBuilder{} + builder.Add("git") + builder.Add("clone") + builder.Add("ssh:test.com/aaa.git") + builder.Add("-b master") + builder.Add("-o origin") + command := builder.Build() + if "git clone ssh:test.com/aaa.git -b master -o origin" != command { + t.Error("build command result is error") + } + + builder.Reset() + builder.Add("git") + builder.Add("pull") + builder.Add("-b master") + builder.Add("-o origin") + command = builder.Build() + if "git pull -b master -o origin" != command { + t.Error("build command result is error") + } + + builder.Reset() + builder.Add("git") + builder.Add("pull") + builder.Add("-b master") + builder.AddWithArgAndCond("-o origin", false) + command = builder.Build() + if "git pull -b master" != command { + t.Error("build command result is error") + } + + builder.Reset() + builder.Add("git") + builder.Add("pull") + builder.Add("-b master") + builder.AddWithArg("-o %s", "origin") + command = builder.Build() + if "git pull -b master -o origin" != command { + t.Error("build command result is error") + } + + builder.Reset() + builder.Add("git") + builder.Add("pull") + builder.Add("-b master") + builder.AddWithArgAndCond("-o %s", false, "origin") + command = builder.Build() + if "git pull -b master" != command { + t.Error("build command result is error") + } +} + +func TestBuildCmdWithArgs(t *testing.T) { + builder := &CmdBuilder{} + builder.Add("git") + builder.AddWithArg("%s %s", "remote", "-v") + command := builder.Build() + if "git remote -v" != command { + t.Error("build command result is error") + } +} + +func TestBuildCmdWithCond(t *testing.T) { + builder := &CmdBuilder{} + builder.Add("git") + builder.Add("clone") + builder.Add("ssh:test.com/aaa.git") + builder.Add("-b master") + builder.AddWithCond("-o origin", false) + command := builder.Build() + if "git clone ssh:test.com/aaa.git -b master" != command { + t.Error("build command result is error") + } +} diff --git a/util/gitOpeator.go b/util/gitOpeator.go index a1205315b97a6643ab911e91deba6d69a8f2f6f4..f1e154f43c0d032d6cc59b1ab71c464f25b1d994 100644 --- a/util/gitOpeator.go +++ b/util/gitOpeator.go @@ -44,22 +44,28 @@ func PathExists(path string) bool { return false } -func GitClone(origin string, repo string, workDir string, workBranch string) bool { +//GitClone is call git clone +func GitClone(url string, repo string, remote string, workDir string, workBranch string) bool { workPath, err := GetWorkDir(workDir) if err != nil { return false } localDir := filepath.Join(workPath, repo) - remoteAddr := fmt.Sprintf("%s/%s.git", origin, repo) - log.Infof("from %s clone %s.", origin, repo) - command := fmt.Sprintf("git clone -- %s %s", remoteAddr, localDir) - ret := Out(Execute(command)) + remoteAddr := fmt.Sprintf("%s/%s.git", url, repo) + log.Infof("from %s clone %s.", url, repo) + builder := &CmdBuilder{} + builder.Add("git").Add("clone") + builder.Add("-o").Add(remote).Add("--") + builder.Add(remoteAddr).Add(localDir) + ret := Out(Execute(builder.Build())) if !ret { return ret } - command = fmt.Sprintf("git -C %s checkout %s", localDir, workBranch) - if !Status(Execute(command)) { + builder.Reset() + builder.Add("git").Add("-C").Add(localDir) + builder.Add("checkout").Add(workBranch) + if !Status(Execute(builder.Build())) { log.Warnf("switch to %s fail.", workBranch) } return ret @@ -87,58 +93,77 @@ func GitSync(upstream string, origin string, repo string, workDir string) bool { } log.Info("2.1 add upstream fetch url.") - command = fmt.Sprintf("git -C %s remote add upstream %s", localDir, upstreamRemote) - ret = Out(Execute(command)) + builder := &CmdBuilder{} + builder.Add("git").Add("-C").Add(localDir) + builder.Add("remote").Add("add upstream").Add(upstreamRemote) + ret = Out(Execute(builder.Build())) if !ret { return ret } log.Info("2.2 fetch upstream all.") - command = fmt.Sprintf("git -C %s fetch --all --prune --tags", localDir) - ret = Out(Execute(command)) + builder.Reset() + builder.Add("git").Add("-C").Add(localDir) + builder.Add("fetch").Add("--all --prune --tags") + ret = Out(Execute(builder.Build())) if !ret { return ret } - command = fmt.Sprintf("git -C %s branch -r", localDir) + builder.Reset() + builder.Add("git").Add("-C").Add(localDir) + builder.Add("branch -r") var out string - out, ret = GetOut(Execute(command)) + out, ret = GetOut(Execute(builder.Build())) if !ret { return ret } log.Info("2.3 track all branch.") + builder.Reset() + builder.Add("git").Add("-C").Add(localDir) + builder.Add("branch -f") + builder.Add("--track %s").Add("upstream/%s") + tpl := builder.Build() for _, s := range strings.Split(out, "\n") { branchName, ok := getBranchName(s) if ok { - command = fmt.Sprintf("git -C %s branch -f --track %s upstream/%s", localDir, branchName, branchName) + command = fmt.Sprintf(tpl, branchName, branchName) ret = Out(Execute(command)) } } log.Info("2.4 remove upstream fetch url.") - command = fmt.Sprintf("git -C %s remote remove upstream", localDir) - ret = Out(Execute(command)) + builder.Reset() + builder.Add("git").Add("-C").Add(localDir) + builder.Add("remote").Add("remove upstream") + ret = Out(Execute(builder.Build())) if !ret { return ret } log.Info("3.1 add origin url.") - command = fmt.Sprintf("git -C %s remote add origin %s", localDir, originRemote) - ret = Out(Execute(command)) + builder.Reset() + builder.Add("git").Add("-C").Add(localDir) + builder.Add("remote").Add("add origin").Add(originRemote) + ret = Out(Execute(builder.Build())) if !ret { return ret } log.Info("3.2 push origin all.") - command = fmt.Sprintf("git -C %s push origin --all -f", localDir) - ret = Out(Execute(command)) + builder.Reset() + builder.Add("git").Add("-C").Add(localDir) + builder.Add("push").Add("origin --all -f") + ret = Out(Execute(builder.Build())) if !ret { return ret } - command = fmt.Sprintf("git -C %s push origin --tags -f", localDir) - ret = Out(Execute(command)) + builder.Reset() + builder.Add("git").Add("-C").Add(localDir) + builder.Add("push").Add("origin --tags -f") + ret = Out(Execute(builder.Build())) return ret } @@ -192,78 +217,99 @@ func isGit(dirPth string) bool { } func GitPull(localRepo string, force bool) bool { - var command string - - command = fmt.Sprintf("git -C %s symbolic-ref --short HEAD", localRepo) - branch, ret := GetOut(Execute(command)) - - command = fmt.Sprintf("git -C %s fetch --all -v", localRepo) - ret = Out(Execute(command)) + builder := &CmdBuilder{} + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("symbolic-ref --short HEAD") + branch, ret := GetOut(Execute(builder.Build())) + + builder.Reset() + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("fetch --all -v") + ret = Out(Execute(builder.Build())) if force { - command = fmt.Sprintf("git -C %s reset --hard refs/remotes/origin/%s", localRepo, branch) - ret = Out(Execute(command)) + builder.Reset() + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("reset --hard") + builder.AddWithArg("refs/remotes/origin/%s", branch) + ret = Out(Execute(builder.Build())) } - command = fmt.Sprintf("git -C %s pull --all -v", localRepo) - ret = Out(Execute(command)) + builder.Reset() + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("pull --all -v") + ret = Out(Execute(builder.Build())) return ret } func GitRemote(localRepo string) bool { - var command string - - command = fmt.Sprintf("git -C %s remote -v", localRepo) - out, ret := GetOut(Execute(command)) + builder := &CmdBuilder{} + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("remote -v") + out, ret := GetOut(Execute(builder.Build())) log.InfoO(out) - command = fmt.Sprintf("git -C %s symbolic-ref --short HEAD", localRepo) - branch, ret := GetOut(Execute(command)) + builder.Reset() + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("symbolic-ref --short HEAD") + branch, ret := GetOut(Execute(builder.Build())) log.Infof("current branch %s", branch) return ret } func GitCreateBranch(localRepo, newBranch, startPoint string) bool { - var command string - - command = fmt.Sprintf("git -C %s branch %s %s", localRepo, newBranch, startPoint) - ret := Out(Execute(command)) - - command = fmt.Sprintf("git -C %s symbolic-ref --short HEAD", localRepo) - branch, ret := GetOut(Execute(command)) + builder := &CmdBuilder{} + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("branch").Add(newBranch).Add(startPoint) + ret := Out(Execute(builder.Build())) + + builder.Reset() + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("symbolic-ref --short HEAD") + branch, ret := GetOut(Execute(builder.Build())) log.Infof("current branch %s", branch) return ret } func GitSwitchBranch(localRepo, aimBranch string, force bool) bool { - var command string - - command = fmt.Sprintf("git -C %s symbolic-ref --short HEAD", localRepo) - curBranch, ret := GetOut(Execute(command)) + builder := &CmdBuilder{} + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("symbolic-ref --short HEAD") + curBranch, ret := GetOut(Execute(builder.Build())) log.Infof("before switch branch %s", curBranch) if force { - command = fmt.Sprintf("git -C %s clean -df", localRepo) - ret = Out(Execute(command)) - command = fmt.Sprintf("git -C %s reset --hard", localRepo) - ret = Out(Execute(command)) - command = fmt.Sprintf("git -C %s fetch --all", localRepo) - ret = Out(Execute(command)) + builder.Reset() + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("clean -df") + ret = Out(Execute(builder.Build())) + builder.Reset() + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("reset --hard") + ret = Out(Execute(builder.Build())) + builder.Reset() + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("fetch --all") + ret = Out(Execute(builder.Build())) } - command = fmt.Sprintf("git -C %s checkout %s", localRepo, aimBranch) - ret = Out(Execute(command)) + builder.Reset() + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("checkout").Add(aimBranch) + ret = Out(Execute(builder.Build())) - command = fmt.Sprintf("git -C %s symbolic-ref --short HEAD", localRepo) - curBranch, ret = GetOut(Execute(command)) + builder.Reset() + builder.Add("git").Add("-C").Add(localRepo) + builder.Add("symbolic-ref --short HEAD") + curBranch, ret = GetOut(Execute(builder.Build())) log.Infof("after switch branch %s", curBranch) return ret } func GitCommand(localRepo, gitCommand string) bool { - var command string - - command = fmt.Sprintf("git -C %s %s", localRepo, gitCommand) - out, ret := GetOut(Execute(command)) + builder := &CmdBuilder{} + builder.Add("git").Add("-C").Add(localRepo) + builder.Add(gitCommand) + out, ret := GetOut(Execute(builder.Build())) log.InfoO(out) return ret } diff --git a/util/stringUtil_test.go b/util/stringUtil_test.go new file mode 100644 index 0000000000000000000000000000000000000000..a4836fa7cba7a5f40b88259a14fbbc7113cbe6ba --- /dev/null +++ b/util/stringUtil_test.go @@ -0,0 +1,27 @@ +package util + +import "testing" + +func TestMatch(t *testing.T) { + var result = false + result = Match("arpc", "", "") + if !result { + t.Error("empty regex error") + } + result = Match("arpc", "arp", "") + if !result { + t.Error("correct regex error") + } + result = Match("arpc", "arc", "") + if result { + t.Error("incorrect regex error") + } + result = Match("arpc", "arp", "ap") + if !result { + t.Error("incorrect invertRegex error") + } + result = Match("arpc", "arp", "ar") + if result { + t.Error("correct invertRegex error") + } +}