现在,我将runtime.Caller(0)
与path.Dir
和filepath.Abs
结合使用,以获取当前执行文件的路径,并获取相对于它的项目根目录。
所以我想说我是这样的文件夹结构:
$GOPATH/src/example.org/myproject
$GOPATH/src/example.org/myproject/main.go
$GOPATH/src/example.org/myproject/path
$GOPATH/src/example.org/myproject/path/loader.go
如果我想要我的项目根目录,我会调用loader.go,然后使用runtime.Caller(0)
获取其路径,然后向上移动一个文件夹以到达项目根目录。
问题在于使用go test -cover
时执行的文件不再在正常位置,而是在特殊的子目录中进行测试和覆盖分析。
runtime.Caller(0)
给了我以下内容:
example.org/myproject/path/_test/_obj_/loader.go
通过path.Dir
和filepath.Abs
运行会给我:
$GOPATH/src/example.org/myproject/path/example.org/myproject/path/_test/_obj_
当我从那里上去时,我无法到达项目根目录但显然完全不同。所以我的问题是:
是否有任何可靠的方法来获得项目根目录?
答案 0 :(得分:3)
您可以从$GOPATH
env变量:
gp := os.Getenv("GOPATH")
ap := path.Join(gp, "src/example.org/myproject")
fmt.Println(ap)
这将产生paroject目录的绝对路径:
/path/to/gopath/src/example.org/myproject
答案 1 :(得分:2)
请参阅this回答。如果您使用的是go~1.8,func Executable() (string, error)
是我在需要时偶然发现的一个选项。我简要地测试了它与go test -cover
的交互方式,看起来效果很好:
func Executable() (string, error)
Executable返回启动当前进程的可执行文件的路径名。无法保证路径仍指向正确的可执行文件。如果使用符号链接启动进程,则根据操作系统,结果可能是符号链接或它指向的路径。如果需要稳定的结果,path / filepath.EvalSymlinks可能会有所帮助。
package main
import (
"fmt"
"os"
"path"
)
func main() {
e, err := os.Executable()
if err != nil {
panic(err)
}
path := path.Dir(e)
fmt.Println(path)
}
测试:
binpath.go
:
package binpath
import (
"os"
"path"
)
func getBinPath() string {
e, err := os.Executable()
if err != nil {
panic(err)
}
path := path.Dir(e)
return path
}
binpath_test.go
:
package binpath
import (
"fmt"
"testing"
)
func TestGetBinPath(t *testing.T) {
fmt.Println(getBinPath())
}
结果类似于/tmp/go-build465775039/github.com/tworabbits/binpath/_test