diff options
| author | Shulhan <ms@kilabit.info> | 2018-09-13 03:48:30 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2018-09-13 03:48:30 +0700 |
| commit | 063617ef0271519fded1e60146f708a9e919a4ab (patch) | |
| tree | 3f6591ff0135f6eec4b95ed338d68bf7f04ae6f4 | |
| parent | 98322f66df4317f05a960d4eefd540eecbd22092 (diff) | |
| download | beku-063617ef0271519fded1e60146f708a9e919a4ab.tar.xz | |
Replace git and common functions with package share/lib/{git,io}
| -rw-r--r-- | beku_test.go | 68 | ||||
| -rw-r--r-- | common.go | 125 | ||||
| -rw-r--r-- | common_test.go | 230 | ||||
| -rw-r--r-- | env.go | 23 | ||||
| -rw-r--r-- | env_test.go | 8 | ||||
| -rw-r--r-- | go.mod | 4 | ||||
| -rw-r--r-- | go.sum | 10 | ||||
| -rw-r--r-- | package.go | 18 | ||||
| -rw-r--r-- | package_git.go | 348 | ||||
| -rw-r--r-- | package_git_test.go | 140 | ||||
| -rw-r--r-- | package_test.go | 64 |
11 files changed, 89 insertions, 949 deletions
diff --git a/beku_test.go b/beku_test.go index c10c486..29492d3 100644 --- a/beku_test.go +++ b/beku_test.go @@ -7,10 +7,10 @@ package beku import ( "fmt" "go/build" - "io" - "io/ioutil" "os" "testing" + + "github.com/shuLhan/share/lib/test/mock" ) const ( @@ -31,63 +31,6 @@ var ( testStderr *os.File ) -func testInitOutput() (err error) { - testStdout, err = ioutil.TempFile("", "") - if err != nil { - return - } - - testStderr, err = ioutil.TempFile("", "") - if err != nil { - return - } - - defStdout = testStdout - defStderr = testStderr - - return -} - -func testGetOutput(t *testing.T) (stdout, stderr string) { - bout, err := ioutil.ReadAll(defStdout) - if err != nil { - t.Fatal(err) - } - berr, err := ioutil.ReadAll(testStderr) - if err != nil { - t.Fatal(err) - } - - stdout = string(bout) - stderr = string(berr) - - return -} - -func testResetOutput(t *testing.T, truncate bool) { - _, err := testStdout.Seek(0, io.SeekStart) - if err != nil { - t.Fatal(err) - } - - _, err = testStderr.Seek(0, io.SeekStart) - if err != nil { - t.Fatal(err) - } - - if truncate { - testStdout.Truncate(0) - testStderr.Truncate(0) - } -} - -func testPrintOutput(t *testing.T) { - testResetOutput(t, false) - stdout, stderr := testGetOutput(t) - t.Log(">>> stdout:\n", stdout) - t.Log(">>> stderr:\n", stderr) -} - func TestMain(m *testing.M) { orgGOPATH := build.Default.GOPATH @@ -104,11 +47,8 @@ func TestMain(m *testing.M) { build.Default.GOPATH = orgGOPATH }() - err = testInitOutput() - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } + defStdout = mock.Stdout() + defStderr = mock.Stderr() testEnv, err = NewEnvironment(false, false) if err != nil { @@ -5,12 +5,8 @@ package beku import ( - "bufio" "bytes" "fmt" - "io" - "os" - "path/filepath" "strings" ) @@ -65,46 +61,6 @@ func GetCompareURL(remoteURL, oldVer, newVer string) (url string) { } // -// IsDirEmpty will return true if directory is not exist or empty; otherwise -// it will return false. -// -func IsDirEmpty(dir string) (ok bool) { - d, err := os.Open(dir) - if err != nil { - ok = true - return - } - - _, err = d.Readdirnames(1) - if err != nil { - if err == io.EOF { - ok = true - } - } - - _ = d.Close() - - return -} - -// -// IsFileExist will return true if relative path is exist on parent directory; -// otherwise it will return false. -// -func IsFileExist(parent, relpath string) bool { - path := filepath.Join(parent, relpath) - - fi, err := os.Stat(path) - if err != nil { - return false - } - if fi.IsDir() { - return false - } - return true -} - -// // IsIgnoredDir will return true if directory start with "_" or ".", or // equal with "vendor" or "testdata"; otherwise it will return false. // @@ -140,87 +96,6 @@ func IsTagVersion(version string) bool { } // -// RmdirEmptyAll remove directory in path if it's empty until one of the -// parent is not empty. -// -func RmdirEmptyAll(path string) error { - if len(path) == 0 { - return nil - } - fi, err := os.Stat(path) - if err != nil { - return RmdirEmptyAll(filepath.Dir(path)) - } - if !fi.IsDir() { - return nil - } - if !IsDirEmpty(path) { - return nil - } - err = os.Remove(path) - if err != nil { - return err - } - - return RmdirEmptyAll(filepath.Dir(path)) -} - -// -// confirm display a question to standard output and read for answer -// from "in" for simple "y" or "n" answer. -// If "in" is nil, it will set to standard input. -// If "defIsYes" is true and answer is empty (only new line), then it will -// return true. -// -func confirm(in io.Reader, msg string, defIsYes bool) bool { - var ( - r *bufio.Reader - b, answer byte - err error - ) - - if in == nil { - r = bufio.NewReader(os.Stdin) - } else { - r = bufio.NewReader(in) - } - - yon := "[y/N]" - - if defIsYes { - yon = "[Y/n]" - } - - fmt.Printf("%s %s ", msg, yon) - - for { - b, err = r.ReadByte() - if err != nil { - fmt.Fprintln(os.Stderr, err) - break - } - if b == ' ' || b == '\t' { - continue - } - if b == '\n' { - break - } - if answer == 0 { - answer = b - } - } - - if answer == 'y' || answer == 'Y' { - return true - } - if answer == 0 { - return defIsYes - } - - return false -} - -// // parsePkgVersion given the following package-version format "pkg@v1.0.0", it // will return "pkg" and "v1.0.0". // diff --git a/common_test.go b/common_test.go index 09021f1..8e13fa4 100644 --- a/common_test.go +++ b/common_test.go @@ -5,9 +5,6 @@ package beku import ( - "io" - "io/ioutil" - "os" "testing" "github.com/shuLhan/share/lib/test" @@ -56,75 +53,6 @@ func TestGetCompareURL(t *testing.T) { } } -func TestIsDirEmpty(t *testing.T) { - emptyDir := "testdata/dirempty" - err := os.MkdirAll(emptyDir, 0700) - if err != nil { - t.Fatal(err) - } - - cases := []struct { - desc string - path string - exp bool - }{{ - desc: `With dir not exist`, - path: `testdata/notexist`, - exp: true, - }, { - desc: `With dir exist and not empty`, - path: `testdata`, - }, { - desc: `With dir exist and empty`, - path: `testdata/dirempty`, - exp: true, - }} - - for _, c := range cases { - t.Log(c.desc) - - got := IsDirEmpty(c.path) - - test.Assert(t, "", c.exp, got, true) - } -} - -func TestIsFileExist(t *testing.T) { - wd, err := os.Getwd() - if err != nil { - t.Fatal(err) - } - - cases := []struct { - desc, parent, relpath string - exp bool - }{{ - desc: "With directory", - relpath: "testdata", - }, { - desc: "With non existen path", - parent: "/random", - relpath: "file", - }, { - desc: "With file exist without parent", - relpath: "LICENSE", - exp: true, - }, { - desc: "With file exist", - parent: wd, - relpath: "LICENSE", - exp: true, - }} - - for _, c := range cases { - t.Log(c.desc) - - got := IsFileExist(c.parent, c.relpath) - - test.Assert(t, "", c.exp, got, true) - } -} - func TestIsIgnoredDir(t *testing.T) { cases := []struct { name string @@ -207,164 +135,6 @@ func TestIsTagVersion(t *testing.T) { } } -func TestRmdirEmptyAll(t *testing.T) { - cases := []struct { - desc string - createDir string - createFile string - path string - expExist string - expNotExist string - }{{ - desc: "With path as file", - path: "testdata/beku.db", - expExist: "testdata/beku.db", - }, { - desc: "With empty path", - createDir: "testdata/a/b/c/d", - expExist: "testdata/a/b/c/d", - }, { - desc: "With non empty at middle", - createDir: "testdata/a/b/c/d", - createFile: "testdata/a/b/file", - path: "testdata/a/b/c/d", - expExist: "testdata/a/b/file", - expNotExist: "testdata/a/b/c", - }, { - desc: "With first path not exist", - createDir: "testdata/a/b/c", - path: "testdata/a/b/c/d", - expExist: "testdata/a/b/file", - expNotExist: "testdata/a/b/c", - }, { - desc: "With non empty at parent", - createDir: "testdata/dirempty/a/b/c/d", - path: "testdata/dirempty/a/b/c/d", - expExist: "testdata", - expNotExist: "testdata/dirempty", - }} - - var ( - err error - f *os.File - ) - for _, c := range cases { - t.Log(c.desc) - - if len(c.createDir) > 0 { - err = os.MkdirAll(c.createDir, 0700) - if err != nil { - t.Fatal(err) - } - } - if len(c.createFile) > 0 { - f, err = os.Create(c.createFile) - if err != nil { - t.Fatal(err) - } - err = f.Close() - if err != nil { - t.Fatal(err) - } - } - - err = RmdirEmptyAll(c.path) - if err != nil { - t.Fatal(err) - } - - if len(c.expExist) > 0 { - _, err = os.Stat(c.expExist) - if err != nil { - t.Fatal(err) - } - } - if len(c.expNotExist) > 0 { - _, err = os.Stat(c.expNotExist) - if !os.IsNotExist(err) { - t.Fatal(err) - } - } - } -} - -func TestConfirm(t *testing.T) { - cases := []struct { - defIsYes bool - answer string - exp bool - }{{ - defIsYes: true, - exp: true, - }, { - defIsYes: true, - answer: " ", - exp: true, - }, { - defIsYes: true, - answer: " no", - exp: false, - }, { - defIsYes: true, - answer: " yes", - exp: true, - }, { - defIsYes: true, - answer: " Ys", - exp: true, - }, { - defIsYes: false, - exp: false, - }, { - defIsYes: false, - answer: "", - exp: false, - }, { - - defIsYes: false, - answer: " no", - exp: false, - }, { - defIsYes: false, - answer: " yes", - exp: true, - }} - - var got bool - - in, err := ioutil.TempFile("", "") - if err != nil { - t.Fatal(err) - } - - defer in.Close() - - for _, c := range cases { - t.Log(c) - - in.WriteString(c.answer + "\n") - - _, err = in.Seek(0, io.SeekStart) - if err != nil { - t.Fatal(err) - } - - got = confirm(in, "confirm", c.defIsYes) - - test.Assert(t, "answer", c.exp, got, true) - - err = in.Truncate(0) - if err != nil { - t.Fatal(err) - } - - _, err = in.Seek(0, io.SeekStart) - if err != nil { - t.Fatal(err) - } - } -} - func TestParsePkgVersion(t *testing.T) { cases := []struct { pkgName string @@ -19,6 +19,7 @@ import ( "strings" "github.com/shuLhan/share/lib/ini" + libio "github.com/shuLhan/share/lib/io" ) // @@ -143,7 +144,7 @@ func (env *Env) cleanUnused() { fmt.Println("[ENV] cleanUnused >>>", pkgPath) _ = os.RemoveAll(pkgPath) - _ = RmdirEmptyAll(pkgPath) + _ = libio.RmdirEmptyAll(pkgPath) } } @@ -225,7 +226,7 @@ func (env *Env) Freeze() (err error) { if env.NoConfirm { env.cleanUnused() } else { - ok = confirm(os.Stdin, msgContinue, false) + ok = libio.ConfirmYesNo(os.Stdin, msgContinue, false) if ok { env.cleanUnused() } @@ -255,7 +256,7 @@ func (env *Env) GetPackage(importPath string) (pkg *Package, err error) { _, err = os.Stat(dirGit) if err != nil { - if IsDirEmpty(fullPath) { + if libio.IsDirEmpty(fullPath) { err = nil } else { err = fmt.Errorf(errDirNotEmpty, fullPath) @@ -708,7 +709,7 @@ func (env *Env) Rescan(firstTime bool) (ok bool, err error) { if env.NoConfirm { ok = true } else { - ok = confirm(os.Stdin, msgContinue, false) + ok = libio.ConfirmYesNo(os.Stdin, msgContinue, false) if !ok { return } @@ -786,7 +787,7 @@ This package is required by, } if !env.NoConfirm { - ok := confirm(os.Stdin, msgContinue, false) + ok := libio.ConfirmYesNo(os.Stdin, msgContinue, false) if !ok { return } @@ -811,7 +812,7 @@ This package is required by, return } - _ = RmdirEmptyAll(pkgImportPath) + _ = libio.RmdirEmptyAll(pkgImportPath) } return @@ -1022,10 +1023,10 @@ func (env *Env) String() string { // install a package. // func (env *Env) install(pkg *Package) (ok bool, err error) { - if !IsDirEmpty(pkg.FullPath) { + if !libio.IsDirEmpty(pkg.FullPath) { fmt.Printf("[ENV] install >>> Directory %s is not empty.\n", pkg.FullPath) if !env.NoConfirm { - ok = confirm(os.Stdin, msgCleanDir, false) + ok = libio.ConfirmYesNo(os.Stdin, msgCleanDir, false) if !ok { return } @@ -1071,7 +1072,7 @@ func (env *Env) update(curPkg, newPkg *Package) (ok bool, err error) { if env.NoConfirm { ok = true } else { - ok = confirm(os.Stdin, msgUpdateView, false) + ok = libio.ConfirmYesNo(os.Stdin, msgUpdateView, false) if ok { err = curPkg.CompareVersion(newPkg) if err != nil { @@ -1083,7 +1084,7 @@ func (env *Env) update(curPkg, newPkg *Package) (ok bool, err error) { if env.NoConfirm { ok = true } else { - ok = confirm(os.Stdin, msgUpdateProceed, true) + ok = libio.ConfirmYesNo(os.Stdin, msgUpdateProceed, true) if !ok { return } @@ -1298,7 +1299,7 @@ func (env *Env) SyncAll() (err error) { fmt.Println(buf.String()) if !env.NoConfirm { - ok := confirm(os.Stdin, msgContinue, false) + ok := libio.ConfirmYesNo(os.Stdin, msgContinue, false) if !ok { return } diff --git a/env_test.go b/env_test.go index 12fbd65..6dd0da1 100644 --- a/env_test.go +++ b/env_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/shuLhan/share/lib/test" + "github.com/shuLhan/share/lib/test/mock" "github.com/shuLhan/tekstus/diff" ) @@ -346,12 +347,13 @@ github.com/ksubedi/gomove 0.2.17 for _, c := range cases { t.Log(c.desc) - testResetOutput(t, true) + mock.Reset(true) testEnv.Query(c.pkgs) - testResetOutput(t, false) - stdout, stderr := testGetOutput(t) + mock.Reset(false) + stdout := mock.Output() + stderr := mock.Error() test.Assert(t, "expStdout", c.expStdout, stdout, true) test.Assert(t, "expStderr", c.expStderr, stderr, true) @@ -2,7 +2,7 @@ module github.com/shuLhan/beku require ( github.com/shuLhan/numerus v0.1.0 // indirect - github.com/shuLhan/share v0.0.0-20180903155519-157a004e9f7c + github.com/shuLhan/share v0.0.0-20180912202720-29654838d11a github.com/shuLhan/tekstus v0.1.0 - golang.org/x/tools v0.0.0-20180831211245-7ca132754999 + golang.org/x/tools v0.0.0-20180911133044-677d2ff680c1 ) @@ -1,9 +1,9 @@ github.com/shuLhan/numerus v0.1.0 h1:oCywZLE3iTb/9T8qhFCkANg59Qy4cJ3nES5+S8WO6/U= github.com/shuLhan/numerus v0.1.0/go.mod h1:zF6WAVSsJebxdZxwyHWhqibDiCXnfitT4oHfcHve7+Y= -github.com/shuLhan/share v0.0.0-20180903155519-157a004e9f7c h1:20x4izLnfln0tqz4aoLRi3G0GoSIgWap3DWdSV/N2yk= -github.com/shuLhan/share v0.0.0-20180903155519-157a004e9f7c/go.mod h1:lzcjs6ErUYp4Frs/NaE+k9lEFS7w1nMEpWAXTImyBSM= +github.com/shuLhan/share v0.0.0-20180912202720-29654838d11a h1:TA6JhhXYj2Pb1D8XW4kZc9lpbAdRKYg3UjeIMfEyy4Y= +github.com/shuLhan/share v0.0.0-20180912202720-29654838d11a/go.mod h1:iFVEXaCAWMpiS3yOJySqq5kCyTCuIxO849OcEATHi7E= github.com/shuLhan/tekstus v0.1.0 h1:O08rXaR8yEZhVTKtgpLfZhEvkRe4svhMhm532tPn4Is= github.com/shuLhan/tekstus v0.1.0/go.mod h1:Pn7xUNXikqBQ1Fqtx2XFZEL1u8nZZPYxfP/8M4+LxaE= -golang.org/x/sys v0.0.0-20180821140842-3b58ed4ad339/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/tools v0.0.0-20180831211245-7ca132754999 h1:mf2VYfMpSMTlp0I/UXrX13w5LejDx34QeUUHH4TrUA8= -golang.org/x/tools v0.0.0-20180831211245-7ca132754999/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/tools v0.0.0-20180911133044-677d2ff680c1 h1:dzEuQYa6+a3gROnSlgly5ERUm4SZKJt+dh+4iSbO+bI= +golang.org/x/tools v0.0.0-20180911133044-677d2ff680c1/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -14,7 +14,9 @@ import ( "sort" "strings" + "github.com/shuLhan/share/lib/git" "github.com/shuLhan/share/lib/ini" + libio "github.com/shuLhan/share/lib/io" "golang.org/x/tools/go/vcs" ) @@ -84,7 +86,7 @@ func NewPackage(env *Env, pkgName, importPath string) ( func (pkg *Package) CheckoutVersion(newVersion string) (err error) { switch pkg.vcsMode { case VCSModeGit: - err = pkg.gitCheckoutVersion(newVersion) + err = git.CheckoutRevision(pkg.FullPath, "", "", newVersion) } return @@ -97,7 +99,7 @@ func (pkg *Package) CheckoutVersion(newVersion string) (err error) { func (pkg *Package) CompareVersion(newPkg *Package) (err error) { switch pkg.vcsMode { case VCSModeGit: - err = pkg.gitCompareVersion(newPkg) + err = git.LogRevisions(pkg.FullPath, pkg.Version, newPkg.Version) } return @@ -110,7 +112,15 @@ func (pkg *Package) CompareVersion(newPkg *Package) (err error) { func (pkg *Package) Fetch() (err error) { switch pkg.vcsMode { case VCSModeGit: - err = pkg.gitFetch() + err = git.FetchAll(pkg.FullPath) + if err != nil { + return + } + if pkg.isTag { + pkg.VersionNext, err = git.LatestTag(pkg.FullPath) + } else { + pkg.VersionNext, err = git.LatestCommit(pkg.FullPath, "") + } } return @@ -209,7 +219,7 @@ func (pkg *Package) Remove() (err error) { return } - _ = RmdirEmptyAll(pkg.FullPath) + _ = libio.RmdirEmptyAll(pkg.FullPath) return } diff --git a/package_git.go b/package_git.go index bdf9b4a..042572e 100644 --- a/package_git.go +++ b/package_git.go @@ -5,252 +5,16 @@ package beku import ( - "bytes" "fmt" - "os" - "os/exec" - "path/filepath" - "github.com/shuLhan/share/lib/ini" + "github.com/shuLhan/share/lib/git" ) // -// gitCheckoutVersion will set the HEAD to version stated in package. -// -// We are not using "git stash", because they introduce many problems when -// rebuilding the package after update. -// -func (pkg *Package) gitCheckoutVersion(version string) (err error) { - if len(version) == 0 { - fmt.Printf("[PKG] gitCheckoutVersion %s >>> empty version\n", - pkg.ImportPath) - return - } - - cmd := exec.Command("git", "clean", "-qdff") - cmd.Dir = pkg.FullPath - cmd.Stdout = defStdout - cmd.Stderr = defStderr - - fmt.Printf("[PKG] gitCheckoutVersion %s >>> %s %s\n", pkg.ImportPath, - cmd.Dir, cmd.Args) - - _ = cmd.Run() - - cmd = exec.Command("git", "checkout", "-t", "origin/master", "-B", "master") - cmd.Dir = pkg.FullPath - cmd.Stdout = defStdout - cmd.Stderr = defStderr - - fmt.Printf("[PKG] gitCheckoutVersion %s >>> %s %s\n", pkg.ImportPath, - cmd.Dir, cmd.Args) - - _ = cmd.Run() - - //nolint:gas - cmd = exec.Command("git", "reset", "--hard", version) - cmd.Dir = pkg.FullPath - cmd.Stdout = defStdout - cmd.Stderr = defStderr - - fmt.Printf("[PKG] gitCheckoutVersion %s >>> %s %s\n", pkg.ImportPath, - cmd.Dir, cmd.Args) - - err = cmd.Run() - if err != nil { - err = fmt.Errorf("gitCheckoutVersion %s: %s", pkg.FullPath, err) - return - } - - return -} - -// -// gitClone the package into "{prefix}/src/{ImportPath}". -// If destination directory is not empty it will return an error. -// -func (pkg *Package) gitClone() (err error) { - err = os.MkdirAll(pkg.FullPath, 0700) - if err != nil { - err = fmt.Errorf("gitClone: %s", err) - return - } - - empty := IsDirEmpty(pkg.FullPath) - if !empty { - err = fmt.Errorf("gitClone: "+errDirNotEmpty, pkg.FullPath) - return - } - - //nolint:gas - cmd := exec.Command("git", "clone", pkg.RemoteURL, ".") - cmd.Dir = pkg.FullPath - cmd.Stdout = defStdout - cmd.Stderr = defStderr - - if Debug >= DebugL1 { - fmt.Printf("[PKG] gitClone %s >>> %s %s\n", pkg.ImportPath, - cmd.Dir, cmd.Args) - } - - err = cmd.Run() - if err != nil { - err = fmt.Errorf("gitClone: %s", err) - return - } - - return -} - -// -// gitCompareVersion compare the version of current package with new package. -// -func (pkg *Package) gitCompareVersion(newPkg *Package) (err error) { - //nolint:gas - cmd := exec.Command("git", "log", "--oneline", pkg.Version+"..."+newPkg.Version) - cmd.Dir = pkg.FullPath - cmd.Stdout = defStdout - cmd.Stderr = defStderr - - if Debug >= DebugL1 { - fmt.Printf("[PKG] gitCompareVersion %s >>> %s %s\n", - pkg.ImportPath, cmd.Dir, cmd.Args) - } - - err = cmd.Run() - if err != nil { - err = fmt.Errorf("gitCompareVersion: %s", err) - return - } - - return -} - -// -// gitFetch will fetch the latest commit from remote. On success, it will set -// the package next version to latest tag (if current package is using tag) or -// to latest commit otherwise. -// -func (pkg *Package) gitFetch() (err error) { - //nolint:gas - cmd := exec.Command("git", "fetch", "--all") - cmd.Dir = pkg.FullPath - cmd.Stdout = defStdout - cmd.Stderr = defStderr - - if Debug >= DebugL1 { - fmt.Printf("[PKG] gitFetch %s >>> %s %s\n", pkg.ImportPath, - cmd.Dir, cmd.Args) - } - - err = cmd.Run() - if err != nil { - err = fmt.Errorf("gitFetch: %s", err) - return - } - - if pkg.isTag { - pkg.VersionNext, err = pkg.gitGetTagLatest() - } else { - ref := filepath.Join(pkg.RemoteName, gitDefBranch) - pkg.VersionNext, err = pkg.gitGetCommit(ref) - } - - return -} - -// -// gitGetCommit will try to get the latest commit hash from "ref" -// (origin/master). -// -func (pkg *Package) gitGetCommit(ref string) (commit string, err error) { - //nolint:gas - cmd := exec.Command("git", "rev-parse", "--short", ref) - cmd.Dir = pkg.FullPath - - if Debug >= DebugL1 { - fmt.Printf("[PKG] gitGetCommit %s >>> %s %s\n", - pkg.ImportPath, cmd.Dir, cmd.Args) - } - - bcommit, err := cmd.Output() - if err != nil { - err = fmt.Errorf("gitGetCommit: %s", err) - return - } - - commit = string(bytes.TrimSpace(bcommit)) - - return -} - -// -// gitGetTag will try to get the current tag from HEAD. -// -func (pkg *Package) gitGetTag() (tag string, err error) { - //nolint:gas - cmd := exec.Command("git", "describe", "--tags", "--exact-match") - cmd.Dir = pkg.FullPath - - if Debug >= DebugL1 { - fmt.Printf("[PKG] gitGetTag %s >>> %s %s\n", pkg.ImportPath, - cmd.Dir, cmd.Args) - } - - btag, err := cmd.Output() - if err != nil { - err = fmt.Errorf("gitGetTag: %s", err) - return - } - - tag = string(bytes.TrimSpace(btag)) - - return -} - -func (pkg *Package) gitGetTagLatest() (tag string, err error) { - //nolint:gas - cmd := exec.Command("git", "rev-list", "--tags", "--max-count=1") - cmd.Dir = pkg.FullPath - - if Debug >= DebugL1 { - fmt.Printf("[PKG] gitGetTagLatest %s >>> %s %s\n", - pkg.ImportPath, cmd.Dir, cmd.Args) - } - - bout, err := cmd.Output() - if err != nil { - err = fmt.Errorf("gitGetTagLatest: %s", err) - return - } - - out := string(bytes.TrimSpace(bout)) - - //nolint:gas - cmd = exec.Command("git", "describe", "--tags", "--abbrev=0", out) - cmd.Dir = pkg.FullPath - - if Debug >= DebugL1 { - fmt.Printf("[PKG] gitGetTagLatest %s >>> %s %s\n", - pkg.ImportPath, cmd.Dir, cmd.Args) - } - - bout, err = cmd.Output() - if err != nil { - err = fmt.Errorf("gitGetTagLatest: %s", err) - return - } - - tag = string(bytes.TrimSpace(bout)) - - return -} - -// // gitInstall the package into source directory. // func (pkg *Package) gitInstall() (err error) { - err = pkg.gitClone() + err = git.Clone(pkg.RemoteURL, pkg.FullPath) if err != nil { err = fmt.Errorf("gitInstall: %s", err) return @@ -258,12 +22,12 @@ func (pkg *Package) gitInstall() (err error) { var rev string if len(pkg.Version) == 0 { - rev, err = pkg.gitGetTagLatest() + rev, err = git.LatestTag(pkg.FullPath) if err == nil { pkg.Version = rev pkg.isTag = IsTagVersion(rev) } else { - rev, err = pkg.gitGetCommit(gitRefHEAD) + rev, err = git.LatestCommit(pkg.FullPath, "") if err != nil { err = fmt.Errorf("gitInstall: %s", err) return @@ -273,51 +37,12 @@ func (pkg *Package) gitInstall() (err error) { } } - err = pkg.gitCheckoutVersion(pkg.Version) - if err != nil { - err = fmt.Errorf("gitInstall: %s", err) - return - } - - return -} - -// -// gitRemoteChange current package remote name (e.g. "origin") or URL to new -// package remote-name or url. -// -func (pkg *Package) gitRemoteChange(newPkg *Package) (err error) { - //nolint:gas - cmd := exec.Command("git", "remote", "remove", pkg.RemoteName) - cmd.Dir = pkg.FullPath - cmd.Stdout = defStdout - cmd.Stderr = defStderr - - if Debug >= DebugL1 { - fmt.Printf("[PKG] gitRemoteChange %s >>> %s %s\n", - pkg.ImportPath, cmd.Dir, cmd.Args) - } - - err = cmd.Run() - if err != nil { - fmt.Fprintln(defStderr, "gitRemoteChange:", err) - } - - //nolint:gas - cmd = exec.Command("git", "remote", "add", newPkg.RemoteName, newPkg.RemoteURL) - cmd.Dir = pkg.FullPath - cmd.Stdout = defStdout - cmd.Stderr = defStderr - - if Debug >= DebugL1 { - fmt.Printf("[PKG] gitRemoteChange %s >>> %s %s\n", - pkg.ImportPath, cmd.Dir, cmd.Args) - } - - err = cmd.Run() - if err != nil { - err = fmt.Errorf("gitRemoteChange: %s", err) - return + if pkg.isTag { + err = git.CheckoutRevision(pkg.FullPath, "", "", pkg.Version) + if err != nil { + err = fmt.Errorf("gitInstall: %s", err) + return + } } return @@ -327,54 +52,12 @@ func (pkg *Package) gitRemoteChange(newPkg *Package) (err error) { // gitScan will scan the package version and remote URL. // func (pkg *Package) gitScan() (err error) { - pkg.Version, err = pkg.gitScanVersion() - if err != nil { - return - } - - err = pkg.gitScanRemote() - - return -} - -func (pkg *Package) gitScanRemote() (err error) { - gitConfig := filepath.Join(pkg.FullPath, gitDir, "config") - - gitIni, err := ini.Open(gitConfig) + pkg.Version, err = git.LatestVersion(pkg.FullPath) if err != nil { - err = fmt.Errorf("gitScanRemote: %s", err) - return - } - - url, ok := gitIni.Get(gitCfgRemote, gitDefRemoteName, gitCfgRemoteURL) - if !ok { - err = fmt.Errorf("gitScanRemote: %s", ErrRemote) - return - } - - pkg.RemoteName = gitDefRemoteName - pkg.RemoteURL = url - - return -} - -// -// gitScanVersion will try to, -// (1) get latest tag from repository first, or if it's fail -// (2) get the commit hash at HEAD. -// -func (pkg *Package) gitScanVersion() (version string, err error) { - // (1) - version, err = pkg.gitGetTag() - if err == nil { return } - // (2) - version, err = pkg.gitGetCommit(gitRefHEAD) - if err != nil { - err = ErrVersion - } + pkg.RemoteURL, err = git.GetRemoteURL(pkg.FullPath, "") return } @@ -385,19 +68,20 @@ func (pkg *Package) gitScanVersion() (version string, err error) { // func (pkg *Package) gitUpdate(newPkg *Package) (err error) { if pkg.RemoteName != newPkg.RemoteName || pkg.RemoteURL != newPkg.RemoteURL { - err = pkg.gitRemoteChange(newPkg) + err = git.RemoteChange(pkg.FullPath, pkg.RemoteName, + newPkg.RemoteName, newPkg.RemoteURL) if err != nil { return } } - err = pkg.gitFetch() + err = git.FetchAll(pkg.FullPath) if err != nil { err = fmt.Errorf("gitUpdate: %s", err) return } - err = pkg.gitCheckoutVersion(newPkg.Version) + err = git.CheckoutRevision(pkg.FullPath, "", "", newPkg.Version) if err != nil { err = fmt.Errorf("gitUpdate: %s", err) } diff --git a/package_git_test.go b/package_git_test.go index 4f36c6f..22c1b74 100644 --- a/package_git_test.go +++ b/package_git_test.go @@ -10,144 +10,6 @@ import ( "github.com/shuLhan/share/lib/test" ) -func testGitCompareVersion(t *testing.T) { - cases := []struct { - desc string - curVersion string - newVersion string - expErr string - expStdout string - expStderr string - }{{ - desc: "With empty versions", - }, { - desc: "With invalid new version", - curVersion: "v0.1.0", - newVersion: "abcdef01", - expErr: "gitCompareVersion: exit status 128", - expStderr: `fatal: ambiguous argument 'v0.1.0...abcdef01': unknown revision or path not in the working tree. -Use '--' to separate paths from revisions, like this: -'git <command> [<revision>...] -- [<file>...]' -`, - }, { - desc: "With empty on new version", - curVersion: "v0.1.0", - expStdout: `582b912 Add feature B. -`, - }, { - desc: "With empty on current version #1", - newVersion: "v0.1.0", - expStdout: `582b912 Add feature B. -`, - }, { - desc: "With empty on current version #2", - newVersion: "v0.2.0", - }, { - desc: "With empty on new version (latest tag)", - curVersion: "v0.2.0", - }, { - desc: "With valid versions", - curVersion: "v0.1.0", - newVersion: "v0.2.0", - expStdout: `582b912 Add feature B. -`, - }, { - desc: "With valid versions, but reversed", - curVersion: "v0.2.0", - newVersion: "v0.1.0", - expStdout: `582b912 Add feature B. -`, - }} - - var ( - err error - stdout, stderr string - ) - - for _, c := range cases { - t.Log(c.desc) - - testGitPkgCur.Version = c.curVersion - testGitPkgNew.Version = c.newVersion - - testResetOutput(t, true) - - err = testGitPkgCur.CompareVersion(testGitPkgNew) - if err != nil { - test.Assert(t, "err", c.expErr, err.Error(), true) - continue - } - - testResetOutput(t, false) - stdout, stderr = testGetOutput(t) - - test.Assert(t, "stdout", c.expStdout, stdout, true) - test.Assert(t, "stderr", c.expStderr, stderr, true) - } -} - -// -// WARNING: This test require internet connection. -// -func testGitFetch(t *testing.T) { - cases := []struct { - desc string - curVersion string - isTag bool - expErr string - expVersionNext string - expStdout string - expStderr string - }{{ - desc: "With tag #1", - curVersion: "v0.1.0", - isTag: true, - expVersionNext: "v0.2.0", - expStdout: `Fetching origin -`, - }, { - desc: "With tag #2", - curVersion: "v0.2.0", - isTag: true, - expVersionNext: "v0.2.0", - expStdout: `Fetching origin -`, - }, { - desc: "With commit hash", - curVersion: "d6ad9da", - expErr: "gitGetCommit: exit status 128", - expVersionNext: "c9f69fb", - expStdout: `Fetching origin -`, - }} - - var ( - err error - stdout, stderr string - ) - - for _, c := range cases { - t.Log(c.desc) - - testGitPkgCur.Version = c.curVersion - testGitPkgCur.isTag = c.isTag - - testResetOutput(t, true) - - err = testGitPkgCur.Fetch() - if err != nil { - test.Assert(t, "err", c.expErr, err.Error(), true) - } - - testResetOutput(t, false) - stdout, stderr = testGetOutput(t) - - test.Assert(t, "VersionNext", c.expVersionNext, testGitPkgCur.VersionNext, true) - test.Assert(t, "stdout", c.expStdout, stdout, true) - test.Assert(t, "stderr", c.expStderr, stderr, true) - } -} - func testGitScan(t *testing.T) { cases := []struct { desc string @@ -206,8 +68,6 @@ func testGitScanDeps(t *testing.T) { } func TestPackageGit(t *testing.T) { - t.Run("CompareVersion", testGitCompareVersion) - t.Run("Fetch", testGitFetch) t.Run("Scan", testGitScan) t.Run("ScanDeps", testGitScanDeps) } diff --git a/package_test.go b/package_test.go index f6e9288..1673ef0 100644 --- a/package_test.go +++ b/package_test.go @@ -13,6 +13,7 @@ import ( "github.com/shuLhan/share/lib/ini" "github.com/shuLhan/share/lib/test" + "github.com/shuLhan/share/lib/test/mock" ) func testPackageRemove(t *testing.T) { @@ -80,18 +81,16 @@ func testPackageInstall(t *testing.T) { }, { desc: `Install again`, pkg: testGitPkgShare, - expErr: fmt.Sprintf("gitInstall: gitClone: "+errDirNotEmpty, testGitPkgShare.FullPath), + expErr: "gitInstall: Clone: exit status 128", }} for _, c := range cases { t.Log(c.desc) - testResetOutput(t, true) + mock.Reset(true) err := c.pkg.Install() - testPrintOutput(t) - if err != nil { test.Assert(t, "err", c.expErr, err.Error(), true) continue @@ -477,12 +476,13 @@ func testGoInstall(t *testing.T) { for _, c := range cases { t.Log(c.desc) - testResetOutput(t, true) + mock.Reset(true) err := c.pkg.GoInstall(testEnv) - testResetOutput(t, false) - stdout, stderr := testGetOutput(t) + mock.Reset(false) + stdout := mock.Output() + stderr := mock.Error() if err != nil { errLines := strings.Split(stderr, "\n") @@ -522,7 +522,7 @@ func testPackageString(t *testing.T) { RemoteName = origin RemoteURL = https://` + testGitRepo + ` Version = v0.2.0 - VersionNext = c9f69fb + VersionNext = IsTag = true Deps = [] RequiredBy = [] @@ -560,12 +560,11 @@ func testUpdate(t *testing.T) { RemoteURL: "git@github.com:shuLhan/beku_test.git", }, expPkg: &Package{ - vcsMode: VCSModeGit, - ImportPath: testGitRepo, - FullPath: filepath.Join(testEnv.dirSrc, testGitRepo), - RemoteName: gitDefRemoteName, - RemoteURL: "git@github.com:shuLhan/beku_test.git", - VersionNext: "c9f69fb", + vcsMode: VCSModeGit, + ImportPath: testGitRepo, + FullPath: filepath.Join(testEnv.dirSrc, testGitRepo), + RemoteName: gitDefRemoteName, + RemoteURL: "git@github.com:shuLhan/beku_test.git", }, }, { desc: "Update version", @@ -586,14 +585,13 @@ func testUpdate(t *testing.T) { isTag: true, }, expPkg: &Package{ - vcsMode: VCSModeGit, - ImportPath: testGitRepo, - FullPath: filepath.Join(testEnv.dirSrc, testGitRepo), - RemoteName: gitDefRemoteName, - RemoteURL: "git@github.com:shuLhan/beku_test.git", - Version: "v0.1.0", - VersionNext: "c9f69fb", - isTag: true, + vcsMode: VCSModeGit, + ImportPath: testGitRepo, + FullPath: filepath.Join(testEnv.dirSrc, testGitRepo), + RemoteName: gitDefRemoteName, + RemoteURL: "git@github.com:shuLhan/beku_test.git", + Version: "v0.1.0", + isTag: true, }, }, { desc: "Update version back", @@ -614,26 +612,26 @@ func testUpdate(t *testing.T) { isTag: true, }, expPkg: &Package{ - vcsMode: VCSModeGit, - ImportPath: testGitRepo, - FullPath: filepath.Join(testEnv.dirSrc, testGitRepo), - RemoteName: gitDefRemoteName, - RemoteURL: "git@github.com:shuLhan/beku_test.git", - Version: "c9f69fb", - VersionNext: "c9f69fb", - isTag: false, + vcsMode: VCSModeGit, + ImportPath: testGitRepo, + FullPath: filepath.Join(testEnv.dirSrc, testGitRepo), + RemoteName: gitDefRemoteName, + RemoteURL: "git@github.com:shuLhan/beku_test.git", + Version: "c9f69fb", + isTag: false, }, }} for _, c := range cases { t.Log(c.desc) - testResetOutput(t, true) + mock.Reset(true) err := c.curPkg.Update(c.newPkg) - testResetOutput(t, false) - stdout, stderr := testGetOutput(t) + mock.Reset(false) + stdout := mock.Output() + stderr := mock.Error() if err != nil { t.Log("stderr:", stderr) |
