繁体   English   中英

如何访问通过 Bazel go_binary 运行的 Go 应用程序内部的数据文件

[英]How to access data files inside Go application running through Bazel go_binary

我有一个包含 go_binary 目标的 BUILD.bazel 文件。 在此应用程序中,我需要访问位于同一目录中的 YAML 文件(例如 config.yml)。

go_binary 看起来像这样:

go_binary(
    name = "app1",
    data = ["config.yml"],
    embed = [":app1_lib"],
    visibility = ["//visibility:public"],
)

我可以看到该文件已添加到/private/var/tmp/_bazel/52b44015c7f2ec78df04b9a822df93c1/execroot/__main__/bazel-out/darwin-fastbuild/bin/services/app1/app1_/app1.runfiles/__main__/services/app1文件夹.

在我的 Go 应用程序中访问此文件的最佳方法是什么?

到目前为止,我发现我可以做到

url := fmt.Sprintf("%s/services/app1/config.yml", os.Getenv("PWD"))

...但我想避免必须明确指定文件夹结构。

这就是您在 Bazel 中访问数据文件的简单方式……您从 WORKSPACE 根目录指定文件的完整路径。 如果您的文件有目标//services/app1:config.yml ,那么路径就是serivces/app1/config.yml

除非出于某种原因需要绝对路径,否则不必为$PWD前缀。 这样做的首选方法是:

const config = "services/app1/config.yml"
abs, err := filepath.Abs(config)
if err != nil {
    return err
}

这假设您没有调用 chdir... 我避免在我的程序中调用 chdir,主要是因为这个原因。

请注意,它不是 URL,如果您需要 URL,您可以:

u := url.URL{Scheme: "file", Path: filepath.ToSlash(abs)}

另请注意,如果您正在处理多个存储库中的文件,则必须包含存储库,并以"external"为前缀。 例如, @some-repo//dir/pkg:targetexternal/some-repo-dir/pkg/target ...即使它只是您的 BUILD 文件中的":target" 呃,对吧?

为什么巴泽尔会这样做?

您的代码可能会将来自您工作区的所有包链接在一起。 看起来很明显,在您的情况下,您只是希望能够从与 package 相同的目录中读取config.yml ,但您同样可以将data = ["config.yml"] go_library()给位于你的deps

为了让它在任何地方都能正常工作,每个人都需要使用数据文件的完整路径。 这有点冗长,但是哦。

如果您genrule go_binary build 规则而不是bazel run调用 go_binary ,则可以将配置文件的路径作为命令行参数传递,如果您愿意的话。 这将允许您在没有完整路径的情况下指定它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM