如何可靠地让项目扎根?

时间:2017-07-21 09:37:28

标签: testing go

现在,我将runtime.Caller(0)path.Dirfilepath.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.Dirfilepath.Abs运行会给我:

$GOPATH/src/example.org/myproject/path/example.org/myproject/path/_test/_obj_

当我从那里上去时,我无法到达项目根目录但显然完全不同。所以我的问题是:
是否有任何可靠的方法来获得项目根目录?

2 个答案:

答案 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