为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕神8447489 2022-10-24 09:22:09
我有一个包含 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"))...但我想避免必须明确指定文件夹结构。
查看完整描述

1 回答

?
慕少森

TA贡献2019条经验 获得超9个赞

这就是您在 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:targetis external/some-repo-dir/pkg/target... 即使它只是":target"在您的 BUILD 文件中。呃,对吧?


为什么巴泽尔会这样做?

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


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


如果您仅调用go_binaryfrom agenrule或 build 规则而不是bazel run,则可以根据需要将配置文件的路径作为命令行参数传递。这将允许您在没有完整路径的情况下指定它。


查看完整回答
反对 回复 2022-10-24
  • 1 回答
  • 0 关注
  • 108 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信