From b080da776abc0cd99c3ccfacb2549d3859df277f Mon Sep 17 00:00:00 2001 From: zav8 Date: Fri, 12 Jul 2019 22:51:38 +0800 Subject: [PATCH] fix controllers parsing issue when go module is enabled. --- generate/swaggergen/g_docs.go | 61 +++++++++++++++-------- utils/utils.go | 91 +++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 21 deletions(-) diff --git a/generate/swaggergen/g_docs.go b/generate/swaggergen/g_docs.go index 512e01c..6080078 100644 --- a/generate/swaggergen/g_docs.go +++ b/generate/swaggergen/g_docs.go @@ -263,7 +263,7 @@ func GenerateDocs(curpath string) { if im.Name != nil { localName = im.Name.Name } - analyseControllerPkg(path.Join(curpath, "vendor"), localName, im.Path.Value) + analyseControllerPkg(curpath, localName, im.Path.Value) } for _, d := range f.Decls { switch specDecl := d.(type) { @@ -418,7 +418,7 @@ func analyseNSInclude(baseurl string, ce *ast.CallExpr) string { return cname } -func analyseControllerPkg(vendorPath, localName, pkgpath string) { +func analyseControllerPkg(curpath, localName, pkgpath string) { pkgpath = strings.Trim(pkgpath, "\"") if isSystemPackage(pkgpath) { return @@ -432,25 +432,9 @@ func analyseControllerPkg(vendorPath, localName, pkgpath string) { pps := strings.Split(pkgpath, "/") importlist[pps[len(pps)-1]] = pkgpath } - gopaths := bu.GetGOPATHs() - if len(gopaths) == 0 { - beeLogger.Log.Fatal("GOPATH environment variable is not set or empty") - } - pkgRealpath := "" - wg, _ := filepath.EvalSymlinks(filepath.Join(vendorPath, pkgpath)) - if utils.FileExists(wg) { - pkgRealpath = wg - } else { - wgopath := gopaths - for _, wg := range wgopath { - wg, _ = filepath.EvalSymlinks(filepath.Join(wg, "src", pkgpath)) - if utils.FileExists(wg) { - pkgRealpath = wg - break - } - } - } + pkgRealpath := resolvePkgPath(pkgpath, curpath) + if pkgRealpath != "" { if _, ok := pkgCache[pkgpath]; ok { return @@ -498,6 +482,41 @@ func analyseControllerPkg(vendorPath, localName, pkgpath string) { } } +// resolvePkgPath resolves the package directory +func resolvePkgPath(pkgpath, curpath string) string { + wg, _ := filepath.EvalSymlinks(filepath.Join(path.Join(curpath, "vendor"), pkgpath)) + if utils.FileExists(wg) { + return wg + } + + gopaths := bu.GetGOPATHs() + modulesEnabled := bu.IsModuleEnabled(gopaths, curpath) + if modulesEnabled { + dirpath := "" + for i, r := range pkgpath { + if r != '/' { + continue + } + dirpath = filepath.Join(curpath, pkgpath[i:]) + if utils.FileExists(dirpath) { + return dirpath + } + } + panic("go module is enabled, and the package path of controllers can not be resolved") + } + + if len(gopaths) == 0 { + beeLogger.Log.Fatal("GOPATH environment variable is not set or empty, or go module is not enabled") + } + for _, gp := range gopaths { + gp, _ = filepath.EvalSymlinks(filepath.Join(gp, "src", pkgpath)) + if utils.FileExists(gp) { + return gp + } + } + return "" +} + func isSystemPackage(pkgpath string) bool { goroot := os.Getenv("GOROOT") if goroot == "" { @@ -802,7 +821,7 @@ func setParamType(para *swagger.Parameter, typ string, pkgpath, controllerName s paraFormat = typeFormat[1] if para.In == "body" { para.Schema = &swagger.Schema{ - Type: paraType, + Type: paraType, Format: paraFormat, } } diff --git a/utils/utils.go b/utils/utils.go index 75b6898..2aa0ff4 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -438,3 +438,94 @@ func defaultGOPATH() string { } return "" } + +// IsModuleEnabled checks whether go module is enabled according to +// https://github.com/golang/go/wiki/Modules#when-do-i-get-old-behavior-vs-new-module-based-behavior +func IsModuleEnabled(gopaths []string, cwd string) bool { + gm := os.Getenv("GO111MODULE") + switch gm { + case "on": + return true + case "off": + return false + default: + for _, gopath := range gopaths { + if gopath == "" { + continue + } + if InDir(cwd, filepath.Join(gopath, "src")) != "" { + return false + } + } + return true + } +} + +// InDir checks whether path is in the file tree rooted at dir. +// If so, InDir returns an equivalent path relative to dir. +// If not, InDir returns an empty string. +// InDir makes some effort to succeed even in the presence of symbolic links. +func InDir(path, dir string) string { + if rel := inDirLex(path, dir); rel != "" { + return rel + } + xpath, err := filepath.EvalSymlinks(path) + if err != nil || xpath == path { + xpath = "" + } else { + if rel := inDirLex(xpath, dir); rel != "" { + return rel + } + } + + xdir, err := filepath.EvalSymlinks(dir) + if err == nil && xdir != dir { + if rel := inDirLex(path, xdir); rel != "" { + return rel + } + if xpath != "" { + if rel := inDirLex(xpath, xdir); rel != "" { + return rel + } + } + } + return "" +} + +// inDirLex is like inDir but only checks the lexical form of the file names. +// It does not consider symbolic links. +// return the suffix. Most uses of str.HasFilePathPrefix should probably +// be calling InDir instead. +func inDirLex(path, dir string) string { + pv := strings.ToUpper(filepath.VolumeName(path)) + dv := strings.ToUpper(filepath.VolumeName(dir)) + path = path[len(pv):] + dir = dir[len(dv):] + switch { + default: + return "" + case pv != dv: + return "" + case len(path) == len(dir): + if path == dir { + return "." + } + return "" + case dir == "": + return path + case len(path) > len(dir): + if dir[len(dir)-1] == filepath.Separator { + if path[:len(dir)] == dir { + return path[len(dir):] + } + return "" + } + if path[len(dir)] == filepath.Separator && path[:len(dir)] == dir { + if len(path) == len(dir)+1 { + return "." + } + return path[len(dir)+1:] + } + return "" + } +}