From 22cf3e37128c33d6c0bbb5cd90af3cb978a1083b Mon Sep 17 00:00:00 2001 From: Frank Martinez Date: Tue, 8 Oct 2019 12:10:00 -0400 Subject: [PATCH] add go src helper --- common/srchelper.go | 1 + go.mod | 6 +- go.mod.build | 6 +- util/gosrchelper.go | 181 +++++++++++++++++++++++++++++++++++++++ util/gosrchelper_test.go | 44 ++++++++++ 5 files changed, 234 insertions(+), 4 deletions(-) create mode 100644 common/srchelper.go create mode 100644 util/gosrchelper.go create mode 100644 util/gosrchelper_test.go diff --git a/common/srchelper.go b/common/srchelper.go new file mode 100644 index 0000000..805d0c7 --- /dev/null +++ b/common/srchelper.go @@ -0,0 +1 @@ +package common diff --git a/go.mod b/go.mod index 815eb5e..8701917 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,12 @@ module github.com/project-flogo/cli require ( + github.com/coreos/go-semver v0.2.0 github.com/msoap/byline v1.1.1 - github.com/project-flogo/core v0.9.0 + github.com/pkg/errors v0.8.1 // indirect + github.com/project-flogo/core v0.9.3 github.com/spf13/cobra v0.0.5 - github.com/stretchr/testify v1.3.0 + github.com/stretchr/testify v1.4.0 ) go 1.12 diff --git a/go.mod.build b/go.mod.build index b327934..70ab36d 100644 --- a/go.mod.build +++ b/go.mod.build @@ -1,8 +1,10 @@ module github.com/project-flogo/cli require ( + github.com/coreos/go-semver v0.2.0 github.com/msoap/byline v1.1.1 - github.com/project-flogo/core v0.9.0 + github.com/pkg/errors v0.8.1 // indirect + github.com/project-flogo/core v0.9.3 github.com/spf13/cobra v0.0.5 - github.com/stretchr/testify v1.3.0 + github.com/stretchr/testify v1.4.0 ) diff --git a/util/gosrchelper.go b/util/gosrchelper.go new file mode 100644 index 0000000..1d7edb6 --- /dev/null +++ b/util/gosrchelper.go @@ -0,0 +1,181 @@ +package util + +import ( + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "strings" + + "github.com/coreos/go-semver/semver" +) + +var goPathCached string + +func FindOldPackageSrc(pkg string) (srcPath, srcVer string, err error) { + + goPath := GetGoPath() + + pkgParts := strings.Split(pkg, "/") + path := filepath.Join(goPath, "src", filepath.Join(pkgParts...)) + + if _, e := os.Stat(path); !os.IsNotExist(e) { + // path/to/whatever exists + v := GetPackageVersionOld(pkg) + + return path, v, nil + } + + return "", "", newPkgNotFoundError(pkg) +} + +func FindGoModPackageSrc(pkg string, version string, latest bool) (srcPath, srcVer string, err error) { + + pkgParts := strings.Split(pkg, "/") + if len(pkgParts) < 2 { + return "", "", fmt.Errorf("invalid package: %s", pkg) + } + + name := pkgParts[len(pkgParts)-1] + path := pkgParts[:len(pkgParts)-1] + + goPath := GetGoPath() + flogoPkgPath := filepath.Join(goPath, "pkg", "mod", filepath.Join(path...)) + + if _, e := os.Stat(flogoPkgPath); os.IsNotExist(e) { + return "", "", newPkgNotFoundError(pkg) + } + + var files []string + + err = filepath.Walk(flogoPkgPath, visit(name, &files)) + if err != nil { + return "", "", newPkgNotFoundError(pkg) + } + + if latest { + + lf := "" + var lv *semver.Version + + for _, file := range files { + + parts := strings.SplitN(file, "@v", 2) + + if lf == "" { + lf = file + lv, err = semver.NewVersion(parts[1]) + if err != nil { + return "", "", err + } + continue + } + + sv, err := semver.NewVersion(parts[1]) + if err != nil { + return "", "", err + } + + if lv.LessThan(*sv) { + lf = file + lv = sv + } + } + + if lf == "" { + return "", "", newPkgNotFoundError(pkg) + } + + return lf, lv.String(), nil + } else { + + for _, file := range files { + + parts := strings.SplitN(file, "@v", 2) + if parts[1] == version { + return file, version, nil + } + } + } + + return "", "", newPkgNotFoundError(pkg) +} + +func visit(name string, files *[]string) filepath.WalkFunc { + return func(path string, info os.FileInfo, err error) error { + if err != nil { + log.Fatal(err) + } + if !info.IsDir() { + return nil + } + + if strings.HasPrefix(info.Name(), name+"@v") { + *files = append(*files, path) + } + + return nil + } +} + +func GetPackageVersionOld(pkg string) string { + re := regexp.MustCompile("\\n") + + cmd := exec.Command("git", "describe", "--tags", "--dirty", "--always") + cmd.Env = append(os.Environ()) + + gopath := GetGoPath() + + pkgParts := strings.Split(pkg, "/") + cmd.Dir = filepath.Join(gopath, "src", filepath.Join(pkgParts...)) + + out, err := cmd.Output() // execute "git describe" + if err != nil { + log.Fatal(err) + } + fc := re.ReplaceAllString(string(out), "") + + if len(fc) > 1 { + return fc[1:] + } + + return fc +} + +func GetGoPath() string { + + if goPathCached != "" { + return goPathCached + } + + set := false + goPathCached, set = os.LookupEnv("GOPATH") + if !set { + out, err := exec.Command("go", "env", "GOPATH").Output() + if err != nil { + log.Fatal(err) + } + goPathCached = strings.TrimSuffix(string(out), "\n") + } + + return goPathCached +} + +func newPkgNotFoundError(pkg string) error { + return &pkgNotFoundError{pkg: pkg} +} + +type pkgNotFoundError struct { + pkg string +} + +func (e *pkgNotFoundError) Error() string { + return fmt.Sprintf("Package '%s' not found", e.pkg) +} + +func IsPkgNotFoundError(err error) bool { + _, ok := err.(*pkgNotFoundError) + return ok +} \ No newline at end of file diff --git a/util/gosrchelper_test.go b/util/gosrchelper_test.go new file mode 100644 index 0000000..b307ce3 --- /dev/null +++ b/util/gosrchelper_test.go @@ -0,0 +1,44 @@ +package util + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestFindGoModPackageSrc(t *testing.T) { + str, ver, err := FindGoModPackageSrc("github.com/project-flogo/core", "", true) + if err != nil { + fmt.Println("err:", err) + t.FailNow() + } + + fmt.Println("path: ", str) + fmt.Println("ver: ", ver) +} + + +func TestFindOldPackageSrc(t *testing.T) { + str, ver, err := FindOldPackageSrc("github.com/project-flogo/cli") + if err != nil { + fmt.Println("err:", err) + t.FailNow() + } + + fmt.Println("path: ", str) + fmt.Println("ver: ", ver) +} + + +func TestFindGoModPackageSrcNotFound(t *testing.T) { + _, _, err := FindGoModPackageSrc("github.com/project-blah/core", "", true) + assert.True(t, IsPkgNotFoundError(err)) + fmt.Println("err: ", err) +} + + +func TestFindOldPackageSrcNotFound(t *testing.T) { + _, _, err := FindOldPackageSrc("github.com/project-blah/core") + assert.True(t, IsPkgNotFoundError(err)) + fmt.Println("err: ", err) +}