From 38ec97de2b612c40e7e692528413c98fbec2d621 Mon Sep 17 00:00:00 2001 From: chmodke <13772804655@163.com> Date: Wed, 5 Apr 2023 20:52:14 +0800 Subject: [PATCH 1/3] =?UTF-8?q?[feature]=E6=96=B0UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 2 +- cmd/batch.go | 7 +- cmd/clone.go | 16 ++-- cmd/create.go | 17 ++-- cmd/list.go | 55 ++++++------- cmd/pull.go | 17 ++-- cmd/remote.go | 7 +- cmd/switch.go | 22 ++---- cmd/sync.go | 18 ++--- log/log.go | 5 +- util/executeCommand.go | 26 +++---- util/gitOpeator.go | 172 +++++++++++++++++++++++++++-------------- util/progress.go | 57 ++++++++++++++ 13 files changed, 252 insertions(+), 169 deletions(-) create mode 100644 util/progress.go diff --git a/Makefile b/Makefile index 8082cf5..9346849 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ BUILD_NAME:=gitmm BIN_DIR:=bin BUILD_MODE?=snapshot -BUILD_VERSION?=1.1.0 +BUILD_VERSION?=1.2.0 BUILD_DATE:=$(shell date '+%Y%m%d.%H%M%S') SOURCE:=*.go diff --git a/cmd/batch.go b/cmd/batch.go index a0f3b46..be981db 100644 --- a/cmd/batch.go +++ b/cmd/batch.go @@ -3,7 +3,6 @@ package cmd import ( "errors" - "fmt" "gitmm/log" "gitmm/util" "path/filepath" @@ -47,17 +46,15 @@ var batchCmd = &cobra.Command{ result := make(map[string]string) for _, repo := range repos { if !util.Match(repo, match, invert) { - log.Info(util.LeftAlign(fmt.Sprintf("skip execute command at %s.\n", repo), 2, "-")) result[repo] = SKIP continue } - log.Info(util.LeftAlign(fmt.Sprintf("start execute command at %s.", repo), 2, "-")) + log.InfoO(repo) ok := util.GitCommand(filepath.Join(localDir, repo), gitCommand) + log.InfoO("") if ok { - log.Info(util.LeftAlign(fmt.Sprintf("execute command at %s done.\n", repo), 2, "-")) result[repo] = OK } else { - log.Error(util.LeftAlign(fmt.Sprintf("execute command at %s fail.\n", repo), 2, "-")) result[repo] = FAIL } } diff --git a/cmd/clone.go b/cmd/clone.go index 1e9a64f..b3a4c73 100644 --- a/cmd/clone.go +++ b/cmd/clone.go @@ -38,24 +38,20 @@ var cloneCmd = &cobra.Command{ log.Debugf("remote-url: %s", url) log.Debugf("repos: %s", config.Repos) - result := make(map[string]string) for _, repo := range config.Repos { + var process util.Progress + process.NewOption(repo, 0, 2) if !util.Match(repo, match, invert) { - log.Info(util.LeftAlign(fmt.Sprintf("skip clone %s.\n", repo), 2, "-")) - result[repo] = SKIP + process.Finish(SKIP) continue } - log.Info(util.LeftAlign(fmt.Sprintf("start clone %s.", repo), 2, "-")) - ok := util.GitClone(url, repo, remote, workDir, workBranch) + ok := util.GitClone(url, repo, remote, workDir, workBranch, &process) if ok { - log.Info(util.LeftAlign(fmt.Sprintf("clone %s done.\n", repo), 2, "-")) - result[repo] = OK + process.Finish(OK) } else { - log.Error(util.LeftAlign(fmt.Sprintf("clone %s fail.\n", repo), 2, "-")) - result[repo] = FAIL + process.Finish(FAIL) } } - util.ExecStatistic("clone", result) }, } diff --git a/cmd/create.go b/cmd/create.go index 3514396..3b53632 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -2,7 +2,6 @@ package cmd import ( - "fmt" "github.com/spf13/cobra" "gitmm/log" "gitmm/util" @@ -36,24 +35,20 @@ var createCmd = &cobra.Command{ if err != nil { log.Error("获取本地仓库失败") } - result := make(map[string]string) for _, repo := range repos { + var process util.Progress + process.NewOption(repo, 0, 1) if !util.Match(repo, match, invert) { - log.Info(util.LeftAlign(fmt.Sprintf("skip create branch at %s.\n", repo), 2, "-")) - result[repo] = SKIP + process.Finish(SKIP) continue } - log.Info(util.LeftAlign(fmt.Sprintf("start create branch at %s.", repo), 2, "-")) - ok := util.GitCreateBranch(filepath.Join(localDir, repo), newBranch, startPoint) + ok := util.GitCreateBranch(filepath.Join(localDir, repo), newBranch, startPoint, &process) if ok { - log.Info(util.LeftAlign(fmt.Sprintf("%s create branch done.\n", repo), 2, "-")) - result[repo] = OK + process.Finish(OK) } else { - log.Error(util.LeftAlign(fmt.Sprintf("%s create branch fail.\n", repo), 2, "-")) - result[repo] = FAIL + process.Finish(FAIL) } } - util.ExecStatistic("create", result) }, } diff --git a/cmd/list.go b/cmd/list.go index a89d3fb..40471b1 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -7,10 +7,14 @@ import ( "gitmm/log" "gitmm/util" "path/filepath" - "strconv" + "strings" ) // listCmd represents the batch command +// name +// status(A D M ?) git status --porcelain +// branch(git branch -l $(git branch --show-current) -v --format='%(upstream)') //%(upstream:remotename) +// lastcommit(git log -n1 --pretty="format:%ad %an" --date=iso) var listCmd = &cobra.Command{ Use: "list", Short: "展示工作路径下的Git仓库信息", @@ -37,41 +41,40 @@ var listCmd = &cobra.Command{ log.Error("获取本地仓库失败") } - 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) + printHead() for _, repo := range repos { if !util.Match(repo, match, invert) { - result[repo] = SKIP continue } - log.InfoO(repo) - - command := fmt.Sprintf("git -C %s remote -v", filepath.Join(localDir, repo)) - remote, _ := util.GetOut(util.Execute(command)) - log.InfoO(remote) - - command = fmt.Sprintf(preCmd, filepath.Join(localDir, repo)) - info, _ := util.GetOut(util.Execute(command)) - log.InfoO(info) - - log.InfoO("") - - result[repo] = OK + repoPath := filepath.Join(localDir, repo) + status := util.GitStatusStatistic(repoPath) + branchName := util.GitCurrentBranch(repoPath) + branchTrack := util.GitBranchTrack(repoPath, branchName) + lastCommit := util.GitLastCommit(repoPath) + printStatus(repo, branchName, branchTrack, lastCommit, status) } - util.ExecStatistic("list", result) return nil }, } +func printHead() { + fmt.Printf("%-15s %-15s %-12s %-33s %-34s\n", "Repo", "BranchName", "TrackTo", "LastCommit", "Status") + fmt.Printf(strings.Repeat("-", 16) + "+" + strings.Repeat("-", 16) + "+" + strings.Repeat("-", 13) + "+" + strings.Repeat("-", 34) + "+" + strings.Repeat("-", 34) + "\n") +} + +func printStatus(repo, branchName, branchTrack, lastCommit string, status map[string]int) { + statusLine := "" + if len(status) > 0 { + for k, v := range status { + statusLine += fmt.Sprintf("%s-%d ", k, v) + } + } else { + statusLine = "clean" + } + fmt.Printf("%-15s %-15s %-12s %-33s %-34s\n", repo, branchName, branchTrack, lastCommit, statusLine) +} + func init() { rootCmd.AddCommand(listCmd) diff --git a/cmd/pull.go b/cmd/pull.go index 211663d..157b156 100644 --- a/cmd/pull.go +++ b/cmd/pull.go @@ -2,7 +2,6 @@ package cmd import ( - "fmt" "github.com/spf13/cobra" "gitmm/log" "gitmm/util" @@ -34,24 +33,20 @@ var pullCmd = &cobra.Command{ if err != nil { log.Error("获取本地仓库失败") } - result := make(map[string]string) for _, repo := range repos { + var process util.Progress + process.NewOption(repo, 0, 4) if !util.Match(repo, match, invert) { - log.Info(util.LeftAlign(fmt.Sprintf("skip pull %s.\n", repo), 2, "-")) - result[repo] = SKIP + process.Finish(SKIP) continue } - log.Info(util.LeftAlign(fmt.Sprintf("start pull %s.", repo), 2, "-")) - ok := util.GitPull(filepath.Join(localDir, repo), force) + ok := util.GitPull(filepath.Join(localDir, repo), force, &process) if ok { - result[repo] = OK - log.Info(util.LeftAlign(fmt.Sprintf("pull %s done.\n", repo), 2, "-")) + process.Finish(OK) } else { - result[repo] = FAIL - log.Error(util.LeftAlign(fmt.Sprintf("pull %s fail.\n", repo), 2, "-")) + process.Finish(FAIL) } } - util.ExecStatistic("pull", result) }, } diff --git a/cmd/remote.go b/cmd/remote.go index 6995bc1..82d0d63 100644 --- a/cmd/remote.go +++ b/cmd/remote.go @@ -2,7 +2,6 @@ package cmd import ( - "fmt" "github.com/spf13/cobra" "gitmm/log" "gitmm/util" @@ -35,17 +34,15 @@ var remoteCmd = &cobra.Command{ result := make(map[string]string) for _, repo := range repos { if !util.Match(repo, match, invert) { - log.Info(util.LeftAlign(fmt.Sprintf("skip show %s remote info.\n", repo), 2, "-")) result[repo] = SKIP continue } - log.Info(util.LeftAlign(fmt.Sprintf("get %s remote info.", repo), 2, "-")) + log.InfoO(repo) ok := util.GitRemote(filepath.Join(localDir, repo)) + log.InfoO("") if ok { - log.Info(util.LeftAlign(fmt.Sprintf("show remote %s done.\n", repo), 2, "-")) result[repo] = OK } else { - log.Error(util.LeftAlign(fmt.Sprintf("show remote %s fail.\n", repo), 2, "-")) result[repo] = FAIL } } diff --git a/cmd/switch.go b/cmd/switch.go index 4cc7651..319e946 100644 --- a/cmd/switch.go +++ b/cmd/switch.go @@ -2,13 +2,10 @@ package cmd import ( - "fmt" + "github.com/spf13/cobra" "gitmm/log" "gitmm/util" "path/filepath" - "strings" - - "github.com/spf13/cobra" ) // switchCmd represents the switch command @@ -38,25 +35,20 @@ var switchCmd = &cobra.Command{ if err != nil { log.Error("获取本地仓库失败") } - result := make(map[string]string) for _, repo := range repos { + var process util.Progress + process.NewOption(repo, 0, 4) if !util.Match(repo, match, invert) { - log.Info(util.LeftAlign(fmt.Sprintf("skip switch %s branch.\n", repo), 2, "-")) - result[repo] = SKIP + process.Finish(SKIP) continue } - log.Info(util.LeftAlign(fmt.Sprintf("start switch %s branch.", repo), 2, "-")) - ok := util.GitSwitchBranch(filepath.Join(localDir, repo), branch, force) + ok := util.GitSwitchBranch(filepath.Join(localDir, repo), branch, force, &process) if ok { - log.Info(util.LeftAlign(fmt.Sprintf("%s switch branch done.\n", repo), 2, "-")) - result[repo] = OK + process.Finish(OK) } else { - log.Error(util.LeftAlign(fmt.Sprintf("%s switch branch fail.\n", repo), 2, "-")) - result[repo] = FAIL + process.Finish(FAIL) } - log.Info(strings.Repeat("-", 80)) } - util.ExecStatistic("switch", result) }, } diff --git a/cmd/sync.go b/cmd/sync.go index 5c37f24..5b0303f 100644 --- a/cmd/sync.go +++ b/cmd/sync.go @@ -27,25 +27,23 @@ var syncCmd = &cobra.Command{ invert, _ := cmd.Flags().GetString("invert-match") log.Debugf("invert: %s", invert) + log.Infof("sync repo from %s to %s.", config.Upstream, config.Origin) + tmp := fmt.Sprintf("_%s_", util.RandCreator(8)) - result := make(map[string]string) for _, repo := range config.Repos { + var process util.Progress + process.NewOption(repo, 0, 9) if !util.Match(repo, match, invert) { - log.Info(util.LeftAlign(fmt.Sprintf("skip %s sync.\n", repo), 2, "-")) - result[repo] = SKIP + process.Finish(SKIP) continue } - log.Info(util.LeftAlign(fmt.Sprintf("start %s sync.", repo), 2, "-")) - ok := util.GitSync(config.Upstream, config.Origin, repo, tmp) + ok := util.GitSync(config.Upstream, config.Origin, repo, tmp, &process) if ok { - log.Info(util.LeftAlign(fmt.Sprintf("sync %s done.\n", repo), 2, "-")) - result[repo] = OK + process.Finish(OK) } else { - log.Error(util.LeftAlign(fmt.Sprintf("sync %s fail.\n", repo), 2, "-")) - result[repo] = FAIL + process.Finish(FAIL) } } - util.ExecStatistic("sync", result) os.RemoveAll(tmp) }, } diff --git a/log/log.go b/log/log.go index 80d6381..00e969e 100644 --- a/log/log.go +++ b/log/log.go @@ -3,7 +3,6 @@ package log import ( "fmt" "strings" - "time" ) var level = INFO @@ -12,7 +11,7 @@ var logLevelMap = make(map[int8]string) var logNameMap = make(map[string]int8) const ( - GlobalFmt = "%s %5s %s\n" + GlobalFmt = "%5s %s\n" DateFormat = "2006-01-02 15:04:05.000" DEBUG int8 = 1 INFO int8 = 3 @@ -138,7 +137,7 @@ func ErrorOf(template string, args ...interface{}) { } func write(level int8, msg string) { - fmt.Printf(GlobalFmt, time.Now().Format(DateFormat), logLevelMap[level], msg) + fmt.Printf(GlobalFmt, logLevelMap[level], msg) } func out(msg string) { diff --git a/util/executeCommand.go b/util/executeCommand.go index 4ff6f1c..6110dc7 100644 --- a/util/executeCommand.go +++ b/util/executeCommand.go @@ -1,8 +1,6 @@ package util -import ( - "gitmm/log" -) +import "gitmm/log" type Charset string @@ -20,31 +18,27 @@ func ExecuteWithCharset(command string, charset Charset) (outStr string, errStr func Status(stdout string, stderr string, err error) bool { if err != nil { + log.Debug(stderr) return false } else { return true } } -func Out(stdout string, stderr string, err error) bool { +func GetOut(stdout string, stderr string, err error) (string, bool) { if err != nil { - log.Error("execute fail") - log.Error(stderr) - return false + log.Debug(stderr) + return "", false } else { - log.Debug("execute succeed") - log.Debug(stdout) - return true + return stdout, true } } -func GetOut(stdout string, stderr string, err error) (string, bool) { +func GetErr(stdout string, stderr string, err error) (string, string, bool) { if err != nil { - log.Error("execute fail") - log.Error(stderr) - return "", false + log.Debug(stderr) + return "", stderr, false } else { - log.Debug("execute succeed") - return stdout, true + return stdout, "", true } } diff --git a/util/gitOpeator.go b/util/gitOpeator.go index f1e154f..7efddc9 100644 --- a/util/gitOpeator.go +++ b/util/gitOpeator.go @@ -44,34 +44,34 @@ func PathExists(path string) bool { return false } -//GitClone is call git clone -func GitClone(url string, repo string, remote string, workDir string, workBranch string) bool { +//GitClone is entry function +func GitClone(url string, repo string, remote string, workDir string, workBranch string, progress *Progress) bool { workPath, err := GetWorkDir(workDir) if err != nil { return false } localDir := filepath.Join(workPath, repo) 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())) + ret := Status(Execute(builder.Build())) if !ret { return ret } + progress.Next() 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) - } + ret = Status(Execute(builder.Build())) + progress.Next() return ret } -func GitSync(upstream string, origin string, repo string, workDir string) bool { +// GitSync is entry function +func GitSync(upstream string, origin string, repo string, workDir string, progress *Progress) bool { upstreamRemote := fmt.Sprintf("%s/%s.git", upstream, repo) originRemote := fmt.Sprintf("%s/%s.git", origin, repo) @@ -84,31 +84,34 @@ func GitSync(upstream string, origin string, repo string, workDir string) bool { var command string var ret bool - log.Infof("sync %s, from %s to %s.", repo, upstream, origin) - log.Info("1.1 init local repo.") + log.Debugf("sync %s, from %s to %s.", repo, upstream, origin) + log.Debug("1.1 init local repo.") command = fmt.Sprintf("git init %s", localDir) - ret = Out(Execute(command)) + ret = Status(Execute(command)) if !ret { return ret } + progress.Next() - log.Info("2.1 add upstream fetch url.") + log.Debug("2.1 add upstream fetch url.") builder := &CmdBuilder{} builder.Add("git").Add("-C").Add(localDir) builder.Add("remote").Add("add upstream").Add(upstreamRemote) - ret = Out(Execute(builder.Build())) + ret = Status(Execute(builder.Build())) if !ret { return ret } + progress.Next() - log.Info("2.2 fetch upstream all.") + log.Debug("2.2 fetch upstream all.") builder.Reset() builder.Add("git").Add("-C").Add(localDir) builder.Add("fetch").Add("--all --prune --tags") - ret = Out(Execute(builder.Build())) + ret = Status(Execute(builder.Build())) if !ret { return ret } + progress.Next() builder.Reset() builder.Add("git").Add("-C").Add(localDir) @@ -118,8 +121,9 @@ func GitSync(upstream string, origin string, repo string, workDir string) bool { if !ret { return ret } + progress.Next() - log.Info("2.3 track all branch.") + log.Debug("2.3 track all branch.") builder.Reset() builder.Add("git").Add("-C").Add(localDir) builder.Add("branch -f") @@ -129,41 +133,46 @@ func GitSync(upstream string, origin string, repo string, workDir string) bool { branchName, ok := getBranchName(s) if ok { command = fmt.Sprintf(tpl, branchName, branchName) - ret = Out(Execute(command)) + ret = Status(Execute(command)) } } + progress.Next() - log.Info("2.4 remove upstream fetch url.") + log.Debug("2.4 remove upstream fetch url.") builder.Reset() builder.Add("git").Add("-C").Add(localDir) builder.Add("remote").Add("remove upstream") - ret = Out(Execute(builder.Build())) + ret = Status(Execute(builder.Build())) if !ret { return ret } + progress.Next() - log.Info("3.1 add origin url.") + log.Debug("3.1 add origin url.") builder.Reset() builder.Add("git").Add("-C").Add(localDir) builder.Add("remote").Add("add origin").Add(originRemote) - ret = Out(Execute(builder.Build())) + ret = Status(Execute(builder.Build())) if !ret { return ret } + progress.Next() - log.Info("3.2 push origin all.") + log.Debug("3.2 push origin all.") builder.Reset() builder.Add("git").Add("-C").Add(localDir) builder.Add("push").Add("origin --all -f") - ret = Out(Execute(builder.Build())) + ret = Status(Execute(builder.Build())) if !ret { return ret } + progress.Next() builder.Reset() builder.Add("git").Add("-C").Add(localDir) builder.Add("push").Add("origin --tags -f") - ret = Out(Execute(builder.Build())) + ret = Status(Execute(builder.Build())) + progress.Next() return ret } @@ -216,27 +225,32 @@ func isGit(dirPth string) bool { return false } -func GitPull(localRepo string, force bool) bool { +// GitPull is entry function +func GitPull(localRepo string, force bool, progress *Progress) bool { builder := &CmdBuilder{} builder.Add("git").Add("-C").Add(localRepo) builder.Add("symbolic-ref --short HEAD") branch, ret := GetOut(Execute(builder.Build())) + progress.Next() builder.Reset() builder.Add("git").Add("-C").Add(localRepo) builder.Add("fetch --all -v") - ret = Out(Execute(builder.Build())) + ret = Status(Execute(builder.Build())) + progress.Next() if force { 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())) + ret = Status(Execute(builder.Build())) } + progress.Next() builder.Reset() builder.Add("git").Add("-C").Add(localRepo) builder.Add("pull --all -v") - ret = Out(Execute(builder.Build())) + ret = Status(Execute(builder.Build())) + progress.Next() return ret } @@ -247,61 +261,48 @@ func GitRemote(localRepo string) bool { out, ret := GetOut(Execute(builder.Build())) log.InfoO(out) - 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 { +func GitCreateBranch(localRepo, newBranch, startPoint string, progress *Progress) bool { builder := &CmdBuilder{} builder.Add("git").Add("-C").Add(localRepo) builder.Add("branch").Add(newBranch).Add(startPoint) - ret := Out(Execute(builder.Build())) + ret := Status(Execute(builder.Build())) + progress.Next() - 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 { +func GitSwitchBranch(localRepo, aimBranch string, force bool, progress *Progress) bool { 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) + ret := false if force { builder.Reset() builder.Add("git").Add("-C").Add(localRepo) builder.Add("clean -df") - ret = Out(Execute(builder.Build())) + ret = Status(Execute(builder.Build())) + progress.Next() builder.Reset() builder.Add("git").Add("-C").Add(localRepo) builder.Add("reset --hard") - ret = Out(Execute(builder.Build())) + ret = Status(Execute(builder.Build())) + progress.Next() builder.Reset() builder.Add("git").Add("-C").Add(localRepo) builder.Add("fetch --all") - ret = Out(Execute(builder.Build())) + ret = Status(Execute(builder.Build())) + progress.Next() + } else { + progress.Skip(3) } builder.Reset() builder.Add("git").Add("-C").Add(localRepo) builder.Add("checkout").Add(aimBranch) - ret = Out(Execute(builder.Build())) - - 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) + ret = Status(Execute(builder.Build())) + progress.Next() return ret } @@ -313,3 +314,62 @@ func GitCommand(localRepo, gitCommand string) bool { log.InfoO(out) return ret } + +func GitStatusStatistic(localRepo string) map[string]int { + status := make(map[string]int) + builder := &CmdBuilder{} + builder.Reset() + builder.Add("git") + builder.AddWithArg("-C %s", localRepo) + builder.Add("status --porcelain") + + out, _ := GetOut(Execute(builder.Build())) + + outData := strings.Split(out, "\n") + for _, line := range outData { + if len(line) > 0 { + s := strings.Split(strings.TrimLeft(line, " "), " ")[0] + status[s]++ + } + } + return status +} + +func GitCurrentBranch(localRepo string) string { + builder := &CmdBuilder{} + builder.Reset() + builder.Add("git") + builder.AddWithArg("-C %s", localRepo) + builder.Add("branch") + builder.Add("--show-current") + + out, _ := GetOut(Execute(builder.Build())) + return out +} + +func GitBranchTrack(localRepo, branchName string) string { + builder := &CmdBuilder{} + builder.Reset() + builder.Add("git") + builder.AddWithArg("-C %s", localRepo) + builder.Add("branch") + builder.Add("-l") + builder.Add(branchName) + builder.Add("-v --format=%(upstream:remotename)") + + out, _ := GetOut(Execute(builder.Build())) + return out +} + +func GitLastCommit(localRepo string) string { + builder := &CmdBuilder{} + builder.Reset() + builder.Add("git") + builder.AddWithArg("-C %s", localRepo) + builder.Add("log") + builder.Add("-n1") + builder.Add("--pretty=\"format:%ad %an\" --date=\"format:%Y/%m/%d %H:%M:%S\"") + + out, _ := GetOut(Execute(builder.Build())) + return out +} diff --git a/util/progress.go b/util/progress.go new file mode 100644 index 0000000..0d579f5 --- /dev/null +++ b/util/progress.go @@ -0,0 +1,57 @@ +package util + +import ( + "fmt" + "math" + "strings" +) + +type Progress struct { + name string //任务名称 + percent int //百分比 + current int //当前进度位置 + total int //总进度 + rate string //进度条 + graph string //显示符号 +} + +func (p *Progress) NewOption(name string, start, total int) { + p.name = fmt.Sprintf("%-20s", name) + p.total = total + if p.graph == "" { + p.graph = "*" + } + p.Play(start) +} + +func (p *Progress) NewOptionWithGraph(name string, start, total int, graph string) { + p.graph = graph + p.NewOption(name, start, total) +} + +func (p *Progress) Next() { + p.Play(p.current + 1) +} + +func (p *Progress) Skip(cnt int) { + p.Play(p.current + cnt) +} + +func (p *Progress) Play(cur int) { + if cur > p.total { + return + } + p.current = cur + p.percent = p.getPercent() + p.rate = strings.Repeat(p.graph, p.percent/2) + fmt.Printf("\r%s[%-50s]%3d%% %8d/%d", p.name, p.rate, p.percent, p.current, p.total) +} + +func (p *Progress) Finish(status string) { + fmt.Printf("\r%s[%-50s]%3d%% %8d/%d %8s", p.name, p.rate, p.percent, p.current, p.total, status) + fmt.Printf("\n") +} + +func (p *Progress) getPercent() int { + return int(math.Min((float64(p.current)/float64(p.total))*100, 100)) +} -- Gitee From 0e65d6e08b78eeabb70c7318c09f9455e40f53cb Mon Sep 17 00:00:00 2001 From: chmodke <13772804655@163.com> Date: Sat, 8 Apr 2023 11:49:33 +0800 Subject: [PATCH 2/3] =?UTF-8?q?[fix]=E6=B8=B8=E7=A6=BB=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E9=80=82=E9=85=8D=EF=BC=8C=E8=A3=81=E5=89=AA=E8=B6=85=E9=95=BF?= =?UTF-8?q?=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 2 +- cmd/list.go | 6 +++--- util/gitOpeator.go | 19 ++++++++++++++++ util/stringUtil.go | 31 ++++++++++++++++++++++++++ util/stringUtil_test.go | 48 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 9346849..af6954c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ BUILD_NAME:=gitmm BIN_DIR:=bin BUILD_MODE?=snapshot -BUILD_VERSION?=1.2.0 +BUILD_VERSION?=1.2.0-alpha BUILD_DATE:=$(shell date '+%Y%m%d.%H%M%S') SOURCE:=*.go diff --git a/cmd/list.go b/cmd/list.go index 40471b1..10be092 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -59,8 +59,8 @@ var listCmd = &cobra.Command{ } func printHead() { - fmt.Printf("%-15s %-15s %-12s %-33s %-34s\n", "Repo", "BranchName", "TrackTo", "LastCommit", "Status") - fmt.Printf(strings.Repeat("-", 16) + "+" + strings.Repeat("-", 16) + "+" + strings.Repeat("-", 13) + "+" + strings.Repeat("-", 34) + "+" + strings.Repeat("-", 34) + "\n") + fmt.Printf("%-16s %-16s %-12s %-34s %-34s\n", "Repo", "BranchName", "TrackTo", "LastCommit", "Status") + fmt.Printf(strings.Repeat("-", 17) + "+" + strings.Repeat("-", 17) + "+" + strings.Repeat("-", 13) + "+" + strings.Repeat("-", 35) + "+" + strings.Repeat("-", 34) + "\n") } func printStatus(repo, branchName, branchTrack, lastCommit string, status map[string]int) { @@ -72,7 +72,7 @@ func printStatus(repo, branchName, branchTrack, lastCommit string, status map[st } else { statusLine = "clean" } - fmt.Printf("%-15s %-15s %-12s %-33s %-34s\n", repo, branchName, branchTrack, lastCommit, statusLine) + fmt.Printf("%-16s %-16s %-12s %-34s %-34s\n", util.RightCut(repo, 16), util.LeftCut(branchName, 16), util.LeftCut(branchTrack, 13), util.LeftCut(lastCommit, 34), statusLine) } func init() { diff --git a/util/gitOpeator.go b/util/gitOpeator.go index 7efddc9..e14f925 100644 --- a/util/gitOpeator.go +++ b/util/gitOpeator.go @@ -344,6 +344,25 @@ func GitCurrentBranch(localRepo string) string { builder.Add("--show-current") out, _ := GetOut(Execute(builder.Build())) + + if len(out) == 0 { + builder.Reset() + builder.Add("git") + builder.AddWithArg("-C %s", localRepo) + builder.Add("tag") + builder.Add("--points-at HEAD") + + out, _ = GetOut(Execute(builder.Build())) + } + if len(out) == 0 { + builder.Reset() + builder.Add("git") + builder.AddWithArg("-C %s", localRepo) + builder.Add("rev-parse") + builder.Add("--short HEAD") + + out, _ = GetOut(Execute(builder.Build())) + } return out } diff --git a/util/stringUtil.go b/util/stringUtil.go index c3390cb..ccd4752 100644 --- a/util/stringUtil.go +++ b/util/stringUtil.go @@ -68,3 +68,34 @@ func RandCreator(l int) string { } return string(result) } + +func RightCut(str string, l int) string { + if l <= 0 { + return "" + } + if len(str) <= l { + return str + } + return str[:l-2] + ".." +} + +func LeftCut(str string, l int) string { + if l <= 0 { + return "" + } + if len(str) <= l { + return str + } + start := len(str) - l + 2 + return ".." + str[start:] +} + +func MaxLen(arr []string) int { + max := 0 + for _, a := range arr { + if len(a) > max { + max = len(a) + } + } + return max +} diff --git a/util/stringUtil_test.go b/util/stringUtil_test.go index a4836fa..be3c1c9 100644 --- a/util/stringUtil_test.go +++ b/util/stringUtil_test.go @@ -25,3 +25,51 @@ func TestMatch(t *testing.T) { t.Error("correct invertRegex error") } } + +func TestRightCut(t *testing.T) { + var result = false + result = "ABCDEFG" == RightCut("ABCDEFG", 8) + if !result { + t.Error("ABCDEFG,8 error") + } + result = "ABCDEFG" == RightCut("ABCDEFG", 7) + if !result { + t.Error("ABCDEFG,7 error") + } + result = "ABCD.." == RightCut("ABCDEFG", 6) + if !result { + t.Error("ABCDEFG,6 error") + } + result = "" == RightCut("ABCDEFG", 0) + if !result { + t.Error("ABCDEFG,0 error") + } + result = "" == RightCut("ABCDEFG", -1) + if !result { + t.Error("ABCDEFG,0 error") + } +} + +func TestLeftCut(t *testing.T) { + var result = false + result = "ABCDEFG" == LeftCut("ABCDEFG", 8) + if !result { + t.Error("ABCDEFG,8 error") + } + result = "ABCDEFG" == LeftCut("ABCDEFG", 7) + if !result { + t.Error("ABCDEFG,7 error") + } + result = "..DEFG" == LeftCut("ABCDEFG", 6) + if !result { + t.Error("ABCDEFG,6 error") + } + result = "" == LeftCut("ABCDEFG", 0) + if !result { + t.Error("ABCDEFG,0 error") + } + result = "" == LeftCut("ABCDEFG", -1) + if !result { + t.Error("ABCDEFG,0 error") + } +} -- Gitee From 6515a40b3d5631c49eaf08f37d5c1696bda5ae6a Mon Sep 17 00:00:00 2001 From: chmodke <13772804655@163.com> Date: Mon, 10 Apr 2023 22:15:13 +0800 Subject: [PATCH 3/3] =?UTF-8?q?[fix]process=E8=A3=81=E5=89=AA=E8=B6=85?= =?UTF-8?q?=E9=95=BF=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 2 +- cmd/clone.go | 2 +- cmd/create.go | 2 +- cmd/pull.go | 2 +- cmd/switch.go | 2 +- cmd/sync.go | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index af6954c..9346849 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ BUILD_NAME:=gitmm BIN_DIR:=bin BUILD_MODE?=snapshot -BUILD_VERSION?=1.2.0-alpha +BUILD_VERSION?=1.2.0 BUILD_DATE:=$(shell date '+%Y%m%d.%H%M%S') SOURCE:=*.go diff --git a/cmd/clone.go b/cmd/clone.go index b3a4c73..bf9bd09 100644 --- a/cmd/clone.go +++ b/cmd/clone.go @@ -40,7 +40,7 @@ var cloneCmd = &cobra.Command{ for _, repo := range config.Repos { var process util.Progress - process.NewOption(repo, 0, 2) + process.NewOption(util.RightCut(repo, 18), 0, 2) if !util.Match(repo, match, invert) { process.Finish(SKIP) continue diff --git a/cmd/create.go b/cmd/create.go index 3b53632..19e2322 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -37,7 +37,7 @@ var createCmd = &cobra.Command{ } for _, repo := range repos { var process util.Progress - process.NewOption(repo, 0, 1) + process.NewOption(util.RightCut(repo, 18), 0, 1) if !util.Match(repo, match, invert) { process.Finish(SKIP) continue diff --git a/cmd/pull.go b/cmd/pull.go index 157b156..f64b538 100644 --- a/cmd/pull.go +++ b/cmd/pull.go @@ -35,7 +35,7 @@ var pullCmd = &cobra.Command{ } for _, repo := range repos { var process util.Progress - process.NewOption(repo, 0, 4) + process.NewOption(util.RightCut(repo, 18), 0, 4) if !util.Match(repo, match, invert) { process.Finish(SKIP) continue diff --git a/cmd/switch.go b/cmd/switch.go index 319e946..bdb8179 100644 --- a/cmd/switch.go +++ b/cmd/switch.go @@ -37,7 +37,7 @@ var switchCmd = &cobra.Command{ } for _, repo := range repos { var process util.Progress - process.NewOption(repo, 0, 4) + process.NewOption(util.RightCut(repo, 18), 0, 4) if !util.Match(repo, match, invert) { process.Finish(SKIP) continue diff --git a/cmd/sync.go b/cmd/sync.go index 5b0303f..e2f3223 100644 --- a/cmd/sync.go +++ b/cmd/sync.go @@ -32,7 +32,7 @@ var syncCmd = &cobra.Command{ tmp := fmt.Sprintf("_%s_", util.RandCreator(8)) for _, repo := range config.Repos { var process util.Progress - process.NewOption(repo, 0, 9) + process.NewOption(util.RightCut(repo, 18), 0, 9) if !util.Match(repo, match, invert) { process.Finish(SKIP) continue -- Gitee