diff --git a/cmd/gf/internal/cmd/cmd_up.go b/cmd/gf/internal/cmd/cmd_up.go index 7f407e324..47851a8d8 100644 --- a/cmd/gf/internal/cmd/cmd_up.go +++ b/cmd/gf/internal/cmd/cmd_up.go @@ -108,14 +108,15 @@ func (c cUp) doUpgradeVersion(ctx context.Context, in cUpInput) (out *doUpgradeV } var ( - dir = gfile.Pwd() - temp string - path = gfile.Join(dir, "go.mod") + temp string + dirPath = gfile.Pwd() + goModPath = gfile.Join(dirPath, "go.mod") ) + // It recursively upgrades the go.mod from sub folder to its parent folders. for { - if gfile.Exists(path) { + if gfile.Exists(goModPath) { var packages []Package - err = gfile.ReadLines(path, func(line string) error { + err = gfile.ReadLines(goModPath, func(line string) error { line = gstr.Trim(line) if gstr.HasPrefix(line, gfPackage) { array := gstr.SplitAndTrim(line, " ") @@ -131,23 +132,28 @@ func (c cUp) doUpgradeVersion(ctx context.Context, in cUpInput) (out *doUpgradeV } for _, pkg := range packages { mlog.Printf(`upgrading "%s" from "%s" to "latest"`, pkg.Name, pkg.Version) - command := fmt.Sprintf(`go get -u %s@latest`, pkg.Name) + // go get -u + command := fmt.Sprintf(`cd %s && go get -u %s@latest`, dirPath, pkg.Name) if err = gproc.ShellRun(ctx, command); err != nil { return } + // go mod tidy + if err = utils.GoModTidy(ctx, dirPath); err != nil { + return nil, err + } out.Items = append(out.Items, doUpgradeVersionOutputItem{ - DirPath: dir, + DirPath: dirPath, Version: pkg.Version, }) } return } - temp = gfile.Dir(dir) - if temp == "" || temp == dir { + temp = gfile.Dir(dirPath) + if temp == "" || temp == dirPath { return } - dir = temp - path = gfile.Join(dir, "go.mod") + dirPath = temp + goModPath = gfile.Join(dirPath, "go.mod") } } diff --git a/cmd/gf/internal/utility/utils/utils.go b/cmd/gf/internal/utility/utils/utils.go index cabc831a6..31394c3e4 100644 --- a/cmd/gf/internal/utility/utils/utils.go +++ b/cmd/gf/internal/utility/utils/utils.go @@ -1,19 +1,14 @@ package utils import ( + "context" "fmt" - "github.com/gogf/gf/v2/errors/gerror" - "github.com/gogf/gf/v2/os/gfile" - "github.com/gogf/gf/v2/text/gstr" - "golang.org/x/tools/imports" - "io" - "net/http" - "os" - "strconv" - "time" - "github.com/gogf/gf/cmd/gf/v2/internal/consts" "github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog" + "github.com/gogf/gf/v2/os/gfile" + "github.com/gogf/gf/v2/os/gproc" + "github.com/gogf/gf/v2/text/gstr" + "golang.org/x/tools/imports" ) // GoFmt formats the source file and adds or removes import statements as necessary. @@ -43,6 +38,13 @@ func GoFmt(path string) { } } +// GoModTidy executes `go mod tidy` at specified directory `dirPath`. +func GoModTidy(ctx context.Context, dirPath string) error { + command := fmt.Sprintf(`cd %s && go mod tidy`, dirPath) + err := gproc.ShellRun(ctx, command) + return err +} + // IsFileDoNotEdit checks and returns whether file contains `do not edit` key. func IsFileDoNotEdit(filePath string) bool { if !gfile.Exists(filePath) { @@ -50,88 +52,3 @@ func IsFileDoNotEdit(filePath string) bool { } return gstr.Contains(gfile.GetContents(filePath), consts.DoNotEditKey) } - -// HTTPDownloadFileWithPercent downloads target url file to local path with percent process printing. -func HTTPDownloadFileWithPercent(url string, localSaveFilePath string) error { - start := time.Now() - out, err := os.Create(localSaveFilePath) - if err != nil { - return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath) - } - defer out.Close() - - headResp, err := http.Head(url) - if err != nil { - return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath) - } - defer headResp.Body.Close() - - size, err := strconv.Atoi(headResp.Header.Get("Content-Length")) - if err != nil { - return gerror.Wrap(err, "retrieve Content-Length failed") - } - doneCh := make(chan int64) - - go doPrintDownloadPercent(doneCh, localSaveFilePath, int64(size)) - - resp, err := http.Get(url) - if err != nil { - return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath) - } - defer resp.Body.Close() - - wroteBytesCount, err := io.Copy(out, resp.Body) - if err != nil { - return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath) - } - - doneCh <- wroteBytesCount - elapsed := time.Since(start) - if elapsed > time.Minute { - mlog.Printf(`download completed in %.0fm`, float64(elapsed)/float64(time.Minute)) - } else { - mlog.Printf(`download completed in %.0fs`, elapsed.Seconds()) - } - - return nil -} - -func doPrintDownloadPercent(doneCh chan int64, localSaveFilePath string, total int64) { - var ( - stop = false - lastPercentFmt string - ) - for { - select { - case <-doneCh: - stop = true - - default: - file, err := os.Open(localSaveFilePath) - if err != nil { - mlog.Fatal(err) - } - fi, err := file.Stat() - if err != nil { - mlog.Fatal(err) - } - size := fi.Size() - if size == 0 { - size = 1 - } - var ( - percent = float64(size) / float64(total) * 100 - percentFmt = fmt.Sprintf(`%.0f`, percent) + "%" - ) - if lastPercentFmt != percentFmt { - lastPercentFmt = percentFmt - mlog.Print(percentFmt) - } - } - - if stop { - break - } - time.Sleep(time.Second) - } -} diff --git a/cmd/gf/internal/utility/utils/utils_http_download.go b/cmd/gf/internal/utility/utils/utils_http_download.go new file mode 100644 index 000000000..e8f5927af --- /dev/null +++ b/cmd/gf/internal/utility/utils/utils_http_download.go @@ -0,0 +1,98 @@ +package utils + +import ( + "fmt" + "github.com/gogf/gf/v2/errors/gerror" + "io" + "net/http" + "os" + "strconv" + "time" + + "github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog" +) + +// HTTPDownloadFileWithPercent downloads target url file to local path with percent process printing. +func HTTPDownloadFileWithPercent(url string, localSaveFilePath string) error { + start := time.Now() + out, err := os.Create(localSaveFilePath) + if err != nil { + return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath) + } + defer out.Close() + + headResp, err := http.Head(url) + if err != nil { + return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath) + } + defer headResp.Body.Close() + + size, err := strconv.Atoi(headResp.Header.Get("Content-Length")) + if err != nil { + return gerror.Wrap(err, "retrieve Content-Length failed") + } + doneCh := make(chan int64) + + go doPrintDownloadPercent(doneCh, localSaveFilePath, int64(size)) + + resp, err := http.Get(url) + if err != nil { + return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath) + } + defer resp.Body.Close() + + wroteBytesCount, err := io.Copy(out, resp.Body) + if err != nil { + return gerror.Wrapf(err, `download "%s" to "%s" failed`, url, localSaveFilePath) + } + + doneCh <- wroteBytesCount + elapsed := time.Since(start) + if elapsed > time.Minute { + mlog.Printf(`download completed in %.0fm`, float64(elapsed)/float64(time.Minute)) + } else { + mlog.Printf(`download completed in %.0fs`, elapsed.Seconds()) + } + + return nil +} + +func doPrintDownloadPercent(doneCh chan int64, localSaveFilePath string, total int64) { + var ( + stop = false + lastPercentFmt string + ) + for { + select { + case <-doneCh: + stop = true + + default: + file, err := os.Open(localSaveFilePath) + if err != nil { + mlog.Fatal(err) + } + fi, err := file.Stat() + if err != nil { + mlog.Fatal(err) + } + size := fi.Size() + if size == 0 { + size = 1 + } + var ( + percent = float64(size) / float64(total) * 100 + percentFmt = fmt.Sprintf(`%.0f`, percent) + "%" + ) + if lastPercentFmt != percentFmt { + lastPercentFmt = percentFmt + mlog.Print(percentFmt) + } + } + + if stop { + break + } + time.Sleep(time.Second) + } +}