如何在go中可靠地获取项目根?

sbdsn5lh  于 2023-08-01  发布在  Go
关注(0)|答案(3)|浏览(147)

现在,我使用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_


当我从那里向上时,我不会到达项目根,但显然是完全不同的东西。所以我的问题是
有没有可靠的方法来获取项目根目录?

92vpleto

92vpleto1#

您可以从$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
这显然只在设置了GOPATH时有效。在你的开发机器上。在生产环境中,您需要通过配置文件提供目录。

p8h8hvxi

p8h8hvxi2#

看到这个答案。如果你使用的是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

uttx8gqw

uttx8gqw3#

Abs返回路径的绝对表示。如果路径不是绝对路径,它将与当前工作目录连接,使其成为绝对路径

absPath, err := filepath.Abs()
if err != nil {
    panic("Ooops)
}

字符串

相关问题